pax_global_header00006660000000000000000000000064144645242740014526gustar00rootroot0000000000000052 comment=ebe9d7d6c4788bb869a07a68a962a5e7ccad47d8 PsimagLite-3.06/000077500000000000000000000000001446452427400135145ustar00rootroot00000000000000PsimagLite-3.06/.clang-format000066400000000000000000000016141446452427400160710ustar00rootroot00000000000000--- # We'll use defaults from the LLVM style, but with 4 columns indentation. BasedOnStyle: WebKit Language: Cpp UseTab: ForContinuationAndIndentation TabWidth: 8 IndentWidth: 8 BreakBeforeBraces: Linux IndentAccessModifiers: false AccessModifierOffset: -8 EmptyLineAfterAccessModifier: Always BraceWrapping: AfterCaseLabel: true AfterClass: true AfterControlStatement: true AfterEnum: true AfterExternBlock: true AfterFunction: true AfterNamespace: true AfterObjCDeclaration: true AfterStruct: true AfterUnion: true AfterExternBlock: false BeforeCatch: true BeforeElse: true BeforeLambdaBody: true IndentBraces: false SplitEmptyFunction: true SplitEmptyRecord: true SplitEmptyNamespace: true BinPackArguments: false BinPackParameters: false ExperimentalAutoDetectBinPacking: false AllowAllParametersOfDeclarationOnNextLine: false --- PsimagLite-3.06/ChangeLog.txt000066400000000000000000000265751446452427400161230ustar00rootroot000000000000002023-08-08 Version 3.06 * expIpi: bug fix * ExpressionForAST replaces ExpressionCalculator * Ainur: Complex numbers now supported * Ainur: Native macros now supported * Geometry: GeometryValueModifier deleted * clang_format added 2022-05-10 Version 3.04 * CanonicalExpression has second optional template * InputNg returns map of key/value pairs * QuasiCanonical allows arithmetic of scalars now * Ainur supports macros now * internode.cpp uses gethostname systemcall now 2021-11-19 Version 3.02 * LinearPrediction now yields correct results (by Alberto Nocera) * LanczosSolver: prefix + EigsForStop= added * NewMake.pm infrastructure: clears .a files (This was affecting KronUtils recompilation in DMRG++) * QuasiCanonical expressions support complex scalars * lorentzian.pl script added * naiztnerol.pl scripts added which does the reverse of lorentzian.pl (Thanks to Bradraj P.) * Ainur: better error reporting * Ainur: allows _ for variable names * Ainur: ellipsis for complex vectors now works * Ainur: full support for complex numbers (Thanks to Pontus L.) * AwesomePredicate and related predicates have changed the characters used for separators and logical operators * ContinuedFraction drivers support complex weights * ExpressionCalculator now works for complex numbers * ExpressionCalculator: ei which means exp(i*variable) has now been fixed (Thanks to Alberto N.) * IoNgSerializer: remembers whether floating points correspond to real or complex 2021-04-22 Version 3.00 * SizeType defaults to long int unsigned * stringToReal supports E uppercase, so that 1E-1 is a valid number * IoNg: overwrite allows unlink to fail * Lanczos and Chebyshev Vectors: swap don't copy * Matrix::swap now with correct semantics * IoNg: various additions to the API 2020-12-02 Version 2.76 * Boost serialization headers deleted * CanonicalExpression: do not throw on empty result to accomodate scalar algebra * Matrix::rotate() added * Matrix::overwrite to hdf5 added * Ainur: throw corrected, and vector of string added 2020-10-27 Version 2.74 * PsimagLite MPI wrapper, called InterNodeMpi, has been added (see mailing list for a description) * LongChain honors IsPeriodicX=1 now * IoNg::dontPrintDebug() now available, which stops canary from singing even in debug mode * CanonicalExpression supports complex scalars now * InputCheckBase added * tutorial with Lesson I: testInputNg * doc.pl supports code sections * Matrix inverse supports float and complex * Star geometry with CENTER == 1 2020-07-31 Version 2.72 * GetBraOrKet: R vectors, like in |R0>, etc, are reserved for internal use * PsimagLite::atoi better error report * Warn if Ainur file with inp file extension; file extensions are still conventions only * Ainur: bug fix for usecomplex * isAfloat: bug fix that affected Awesome Predicate * AinurState.h is no longer a singleton (needed for cincuenta) 2020-03-13 version 2.70 * Matrix expIpi function (Thanks to Jacek) * Awesome Predicate: settings start with @ * GEMMR (Thanks to Ed) * Parallelization at nested level * Ainur: atoi and atof check their arguments now (Thanks to Pontus) * OneOperatorSpec: better error reporting (Thanks to Bradraj) * SizeType is uint64_t by default now 2020-01-14 version 2.68 * OstringStream changes done for precision * PredicateAwesome supports 3 name/value pairs * Geometry fillAdditionalData deleted * GeometryBase nullptr means super connections * CrsMatrix: A cross B added; other improvements * pthread_exit now called explicitly to help profiling tools 2019-12-09 version 2.66 * GetBraOrKet: Quantum sector before excited level * LanczosSolver: early exit has new algorithm for excited states * OneOperatorSpec has generalization * PredicateAwesome: bug fix and new features * CrsMatrix: performance improvements by Ed * Ainur supports complex numbers now 2019-11-08 version 2.64 * libpsimaglite can now be built without HDF5 * GetBraOrKet has new interface 2019-09-23 version 2.62 new drivers * isBlasThreaded and openBlasConfig new features and interfaces * PredicateAwesome supports constants * Parallelizer2 replaces Parallelizer * sfinae examples started 2019-08-13 Version 2.60 bug fixes * Matrix::operator+= : resize if needed * Ainur: still not working for Complex matrices performance * externalProduct now permutes rows and cols on-the-fly new features * PredicateAwesome 2019-06-25 Version 2.58 * GetBraOrKet now in PsimagLite * Geometry LongRange supports Entangler * InputNg::Writeable can take data in string, and in file 2019-05-20 Version 2.56 * OneOperatorSpec moved to PsimagLite so that Lanczos++ can use it * Changes needed by YaSpinWave * PsiScript.pl6 added to execute scripts * PsiTag now supports append, delete, and strict modes * PsiTag proposal for modifiers * Ladder geometry now supports odd legs * Ladder geometry now honors IsPeriodicX=1 * LongRange geometry now requires GeometryMaxConnections= (set to 0 if in doubt) 2019-04-02 Version 2.54 Bug fixes: * ContinuedFractionCollection driver: write fixed New features: * InputNg: supports replacements * ParametersForLanczosSolver: rabbit hole algorithm used now Refactoring * basenameOf now available 2019-03-07 Version 2.52 * PthreadsNg compiles on MacOS * Ainur: better error reporting * CanonicalExpression no longer needs default ctor for ResultType 2019-01-31 Version 2.50 * IsEnumClass predicate * IoNg: read/write enum class * PsiApp: microarchitecture compile vs. runtime check * All programs that need PsimagLite must use C++11 now 2019-01-22 Version 2.48 * PthreadsNg: setAffinities with new algorithm * TridiagonalMatrix.cpp: bug fix in dstedc_ * Svd.h: no fallback on failure; warning printed 2019-01-03 Version 2.46 * C++11 required * Geometry::AdditionalData is a vector of unsigned ints * DegreesOfFreedom= creates orbitals per term * PsiDoc: capture first proto and first function with marks inside functions 2018-12-19 Version 2.44 * boost-spirit now needed to compile (only headers used; the boost runtime is NOT used) 2018-12-10 Version 2.42 New features: * PsiApp::echoBase64 * PsiApp:;printCmdLine * PsiTag: PSITAG_CONFIG_USER env variable 2018-10-25 Version 2.40 Bug fixes * LanczosCore can now handle matrices of rows = cols = 1 New features: * IoNg: more overwrites possible Refactoring: * TimeHandle class 2018-09-27 Version 2.38 * new LanczosSolver by Nirav * ProgressIndicator prints to milliseconds 2018-09-11 Version 2.36 * IoNgSerializer: bug fix in reading/writing a single boolean * added test drivers for Lanczos * MemoryUsage and ProgressIndicator can track time in microseconds 2018-08-30 Version 2.34 * IMPORTANT: BUG FIX in saving and reading booleans with IoNgSerializer * IoNg::In can return serializer object * testIoNgBoolean driver added * DeepCopyOrNot helper class added 2018-08-21 Version 2.32 * Geometry::AdditionalData simplified * isAntiHermitian available for CRS and Matrix 2018-08-09 Version 2.30 * ConfigBase.psiTag: can override default compiler * Compiles on a MAC 2018-07-31 Version 2.28 * configure.pl uses PsiTag 2018-07-24 Version 2.26 * PsiTag: recursive behavior * indexOrMinusOne * NewMake improvments * Profiling takes message strings * Matrix::reset gone, Matrix::resize changed Matrix ctor added. Thanks to Ed for suggestions * LanczosVectors changes to matrix allocation 2018-07-12 Version 2.24 * prints GEOMETRY with IoNg * IoNgSerializer doesGroupExist * IoNgSerializer ctor can be inside try/catch block * PsiTag * new build system * TypesEqual and IndexOfItem added * CrsMatrix::conjugate() added 2018-06-28 Version 2.22 * USE_IO_NG deleted, USE_IO_SIMPLE added * ProgressIndicator::time() added * IoSimple and IoNg cleanup * IoNg holds filename and mode * IoNg improvements * IoNg: bug fixed in writeVectorEntry * IoNg: has canary, but can be improved 2018-06-19 Version 2.20 * myApp01.cpp sample PsimagLite app * IoNg: pairs read/write 2018-05-21 Version 2.18 * IoNg fixes * USE_IO_NG enabled by default * compiler switches, supports clang++ * testIoNg compiles * CRS: sum function for multiple matrices (Contributed by Ed) * Profiling class changed 2018-05-08 Version 2.16 * IoNg for bool and std::vector * CrsMatrix fullMatrixToCrsMatrix preallocates memory * Matrix: svd fallback * Parallelizer API changes * PsimagLite manual started 2018-04-24 Version 2.14 * IoNg work * src/Io/ directory 2018-04-16 Version 2.12 * IoNg work in progress 2018-04-06 Version 2.10 * Honeycomb geometry added supports periodicity in x and y HoneycombLy must be a multiple of 4 * serialization selection and serialization with IoNg * svd with float * float compilation * clang++ compilation * -Werror not set by default in production But please report compilation warnings so that they can be corrected 2018-03-22 Version 2.08 * IoNg work in progress * minimizer test compiles * Ainur: added test inputs * DependenciesTest.txt added for testing dependencies 2018-02-27 Version 2.06 * CRS: Many improvements suggested by Ed, including memory preallocation in many functions 2018-02-20 Version 2.04 * make.pl for drivers updated * IoNg work started * CRS: unneeded externalProducts commented out 2018-02-08 Version 2.02 * LanczosVectors storage managed internally * PSI_PUBSETBUF should be set for lustre filesystem to disable buffering. 2018-01-25 Version 2.00 * Lanczos Solver reortho now possible 2017-01-03 Version 1.80 * IoSimple: unbuffered output 2017-12-20 Version 1.78 * Nested pthreads example added 2017-11-30 Version 1.76 * LanczosSolver: clean up 2017-11-27 Version 1.74 * LanczosSolver: initialize finalize hooks 2017-11-09 Version 1.72 * Ainur improvements * clang compilation fix 2017-09-20 Version 1.70 * scripts: perl open with 3 arguments * Ainur: reads non-complex inputs 2017-08-28 Version 1.68 * Ainur: boost-spirit backend * USE_BOOST: optional compilation with boost * deleted gitrev * rows() and cols() for most matrix types 2017-08-07 Version 1.66 * Matrix class: new ctor, clear and data members * NO_DEPRECATED_ALLOWED preprocessor flag * CrsMatrix isZero default optional arg. is 0 * LAPACK: print if not thread safe * Ainur new input system: very early implementation * Ainur new input system: hooked up * IsInputLike and IsOutputLike predicates for EnableIf * Make.pm: clean target may be appended to * some "template constraints" added 2017-06-15 Version 1.64 * Domain checks for operator+= in Matrix * Make.pm, newMake function takes pointer to hash as third argument 2017-06-08 Version 1.62 * faster isZero function for CrsMatrix * transpose of Matrix added (without conjugate) 2017-05-25 Version 1.60 * Lanczos: saves LanczosVectors by the default Internally lotaMemory=true is the default prefix + NoSaveLanczosVectors=1 should be used to have Lanczos not save vectors * svd: complex version and optimal lwork 2017-05-18 version 1.58 * PTHREAD_ASSIGN_AFFINITIES removed, now a runtime option * LanczosSolver: checks for success of memory alloc. * svd implementation now in Matrix.cpp 2017-05-11 version 1.56 * PthreadsNg: LoadBalancerDefault assigns largest weight first * err function added 2017-05-04 Version 1.54 * JSON Library removed * PsiApp class added * Make.pm takes path * log2Integer function added * LAPACK algorithm for lwork changed 2017-04-24 Version 1.52 * Geometry: Ladder: Reads IsPeriodicX/Y * Makefile: -lblas -llapack * Matrices: rows() cols() interface PsimagLite-3.06/LICENSE000066400000000000000000000067741446452427400145370ustar00rootroot00000000000000Copyright (c) 2009-2011 , UT-Battelle, LLC All rights reserved [PsimagLite, Version 1.0.0] [by G.A. and M.S., Oak Ridge National Laboratory] UT Battelle Open Source Software License 11242008 OPEN SOURCE LICENSE Subject to the conditions of this License, each contributor to this software hereby grants, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to use, copy, modify, merge, publish, distribute, and/or sublicense copies of the Software. 1. Redistributions of Software must retain the above copyright and license notices, this list of conditions, and the following disclaimer. Changes or modifications to, or derivative works of, the Software should be noted with comments and the contributor and organization's name. 2. Neither the names of UT-Battelle, LLC or the Department of Energy nor the names of the Software contributors may be used to endorse or promote products derived from this software without specific prior written permission of UT-Battelle. 3. The software and the end-user documentation included with the redistribution, with or without modification, must include the following acknowledgment: "This product includes software produced by UT-Battelle, LLC under Contract No. DE-AC05-00OR22725 with the Department of Energy." ********************************************************* DISCLAIMER THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS. ********************************************************* Files under loki have the following: //////////////////////////////////////////////////////////////////////////////// // The Loki Library // Copyright (c) 2001 by Andrei Alexandrescu // This code accompanies the book: // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design // Patterns Applied". Copyright (c) 2001. Addison-Wesley. // Permission to use, copy, modify, distribute and sell this software for any // purpose is hereby granted without fee, provided that the above copyright // notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. // The author or Addison-Welsey Longman make no representations about the // suitability of this software for any purpose. It is provided "as is" // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// PsimagLite-3.06/PolicyRegardingRegressions.txt000066400000000000000000000032521446452427400215650ustar00rootroot00000000000000MEMO: Policy Regarding Regressions DATE: January 31st, 2017 TYPE OF MEMO: Normative 1.1 Definition. A software regression is a fault in the software that was not present in a previous revision. The types of faults covered in this MEMO are listed below, under section 2. 1.2 Policy. Regressions are not allowed in any of our codes. 1.3 Reporting procedure. If you find a regression please submit the git revision hashes for the old revision for the relevant code, and all codes that depend on it. Submit also the conditions (input decks, cores used, etc) under which the regression can be reproduced. 2. Regressions Types 2.1 Bugs that cause the code to give wrong results, where correct results where obtained before, under the same or similar conditions. 2.2 Bugs that cause the code to segfault, where it did not segfault before, under the same or similar conditions. 2.3 Bugs that cause a race condition, where a race condition was not present before, under the same or similar conditions. 2.4 Changes that caused established useful functionality to be removed, without alternative ways of accessing said functionality in the current revision, under the same or similar conditions. 2.5 Changes that cause the code to use an impractical amount of RAM or disk, where an impractical amount of RAM or disk was not used before, under the same or similar conditions. 2.6 Changes that cause the code to use unnecessary amount of RAM or disk, where an unnecessary amount of RAM or disk was not used before, under the same or similar conditions. 2.7 Changes that negatively affect the performance of the code in a practical way, compared to a previous revision, under the same or similar conditions. PsimagLite-3.06/PsimagDoc/000077500000000000000000000000001446452427400153625ustar00rootroot00000000000000PsimagLite-3.06/PsimagDoc/README000066400000000000000000000052071446452427400162460ustar00rootroot00000000000000Introducing PsimagDoc PsimagLite v1.0 Copyright (c) 2011, UT-Battelle, LLC All rights reserved [by G.A., Oak Ridge National Laboratory] ********************************************************* DISCLAIMER THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS. ********************************************************* Synopsis: Creates a .tex document from a .ptex document perl psimagdoc.pl < document.ptex > document.tex Description: A .ptex document is a valid .tex document with certain TeX commands like \ptexPaste{...} that enables the introduction of pieces of documentations that are scattered in the code. Doxygen needs to be run on the code with this option: GENERATE_PERLMOD = YES in the Doxygen file. The script psimagdoc.pl will then load all documentation (that must conform to Doxygen's rules) and use it to replace \ptexPaste{...} entries in document.ptex to create document.tex. All this should happen automatically, and it already does for DMRG++. So, in this case you obtain a doc/manual.pdf document when you run make in your DMRG++ distribution. Available Commands: \ptexPaste{class,function} please use Doxygen's rules to specify classes and functions. For examples, see doc/manual.ptex in your DMRG++ distribution. \ptexReadFile{filename} Dumps the unprocessed file into the document. Legacy: PsimagDoc replaces pTeX.pl, and my previous tool multiweb which was based on nuweb. Documentation in files will---slowly---be transformed into Doxygen, so that it can be processed with PsimagDoc. See also: Doxygen's perlmod documentation, http://www.stack.nl/~dimitri/doxygen/perlmod.html DMRG++ doc/manual.ptex file PsimagLite-3.06/PsimagDoc/psimagdoc.pl000066400000000000000000000063251446452427400176730ustar00rootroot00000000000000#!/usr/bin/perl -w use warnings; use strict; our $doxydocs; use lib 'doxygen/perlmod'; use DoxyDocs; my $startPtr = $doxydocs; my $foundHash; my $verbose = 0; while() { next if (/\\newcommand\{\\ptex/); if (/\\ptexPaste\{([^\}]+)\}/) { my $x = $1; my @temp=split/,/,$x; die "$0: Syntax error for \\ptexPaste line $.\n" if ($#temp<0); $foundHash=\$x; my $ptr = $startPtr->{"classes"}; if ($temp[0]=~s/(^!)//) { $ptr = $startPtr->{"files"}; } findClassOrFile($ptr,$temp[0],\$foundHash); (UNIVERSAL::isa( $foundHash, "HASH" )) or die "$0: Not found file or class $x at line $.\n"; if ($#temp>=1) { my $nameOfKind = $temp[1]; my $kind = "variable"; if ($nameOfKind=~s/\(\)$//) { $kind="function"; } findKind($foundHash,$nameOfKind,\$foundHash,$kind); (UNIVERSAL::isa( $foundHash, "HASH" )) or die "$0: Not found function $x\n"; printHash($foundHash) if ($verbose); } $x = $temp[0]; my $substitution = getDetailed($foundHash); $substitution =~ s/!PTEX_THISCLASS/$x/g; s/\\ptexPaste\{([^\}]+)\}/$substitution/; } if (/\\ptexReadFile\{([^\}]+)\}/) { print STDERR "Reading $1\n" if ($verbose); readFile($1); next; } print; } sub readFile { my ($file)=@_; open(FILE, "<", $file) or die "Cannot open $file: $!\n"; while() { print; } close(FILE); } sub getDetailed { my ($ptr)=@_; my $x = $ptr->{"detailed"}->{"doc"}; my $buffer = ""; for my $item (@$x) { $buffer .= procTextual($item); } return $buffer; } sub procTextual { my ($ptr)=@_; my $type = $ptr->{"type"}; return "\n\n" if ($type eq "parbreak"); return "$type" unless ($type eq "text"); my $content = $ptr->{"content"}; defined($content) or $content=""; return $content; } sub printHash { my ($ptr)=@_; for my $item (keys %$ptr) { my $value = $ptr->{$item}; print STDERR "key=$item value=$value\n"; } } sub findClassOrFile { my ($ptr,$thisClassOrFile,$foundHash)=@_; for my $item (@$ptr) { if ($item->{"name"} eq $thisClassOrFile) { $$foundHash = $item; return; } } } sub findKind { my ($ptr,$thisFunc,$foundHash,$kind)=@_; my ($lastKind,$lastName)=("",""); for my $item (keys %$ptr) { print STDERR "key=$item\n" if ($verbose); my $x = $ptr->{$item}; if (UNIVERSAL::isa( $x, "HASH" )) { findKind($x,$thisFunc,$foundHash,$kind); next; } elsif (UNIVERSAL::isa( $x, "ARRAY" )) { findKindA($x,$thisFunc,$foundHash,$kind); next; } if ($item eq "kind") { $lastKind = $x; print STDERR "lastKind=$lastKind\n" if ($verbose); } if ($item eq "name") { $lastName = $x; print STDERR "lastName $lastName and thisFunc= $thisFunc\n" if ($verbose); } if ($lastName eq $thisFunc) { next if (defined($kind) and !($lastKind eq $kind)); $$foundHash = $ptr; print STDERR "Found for hash $$foundHash\n" if ($verbose); return; } } } sub findKindA { my ($ptr,$thisFunc,$foundHash,$kind)=@_; for my $item (@$ptr) { print STDERR "findKindA key=$item\n" if ($verbose); my $x = $item; if (UNIVERSAL::isa( $x, "HASH" )) { findKind($x,$thisFunc,$foundHash,$kind); } elsif (UNIVERSAL::isa( $x, "ARRAY" )) { findKindA($x,$thisFunc,$foundHash,$kind); } else { print STDERR "findKindA value=$x\n" if ($verbose); } } } PsimagLite-3.06/README.md000066400000000000000000000041401446452427400147720ustar00rootroot00000000000000 # Quick Start ## Introduction PsimagLite is free software (see file LICENSE) Parts might have its own License. See Parts of PsimagLite below. Please cite PsimagLite if you base any scientific publication on this software. Citation should read: G. Alvarez, (2011), PsimagLite (version 1.0) [computer software], Oak Ridge National Laboratory. ------------------------------------------------------------------------------- ## Disclaimer THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS. ## Description PsimagLite is a collection of C++ classes that are common to codes for the simulation of strongly correlated electrons. PsimagLite is inspired in T.S.'s Psimag software (but PsimagLite is not a fork of Psimag). The reason for PsimagLite is to share code among different applications. Applications that depend on PsimagLite are: SpinPhononFermion, DMRG++, Lanczos++, FreeFermions, GpusDoneRight, BetheAnsatz ## Code integrity Hash of the latest commit is also posted at https://g1257.github.com/hashes.html Latest commit should always be signed. Keys at https://g1257.github.com/keys.html PsimagLite-3.06/TestSuite/000077500000000000000000000000001446452427400154455ustar00rootroot00000000000000PsimagLite-3.06/TestSuite/OracleCreator.pl000066400000000000000000000006261446452427400205330ustar00rootroot00000000000000#!/usr/bin/perl -w use warnings; use strict; package OracleCreator; sub doMain { my ($doIt,$roots)=@_; $doIt = 0 if (!defined($doIt)); foreach (@$roots) { doThisRoot($_); } } sub doThisRoot { my ($root)=@_; for ($i=0;$i<800;$i++) { my $f = "$root$i.txt"; next unless (-r "results/$f"); system("cp results/$f oracles/$f") if ($doIt); print STDERR "cp results/$f oracles/$f\n"; } } 1; PsimagLite-3.06/TestSuite/README000066400000000000000000000126501446452427400163310ustar00rootroot00000000000000PsimagLite v1.0 Copyright (c) 2011, UT-Battelle, LLC All rights reserved [by G.A., Oak Ridge National Laboratory] [TestSuite contribution by E.P., Oak Ridge National Laboratory] ********************************************************* DISCLAIMER THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS. ********************************************************* The TestSuite is run as follows: cd TestSuite ./testsuite.pl -a to run all tests. Individual tests can be run with ./testsuite.pl -n N where N is the test number. Results, and most importantly diffs, are written to TestSuite/results For example, for SPFv7 you will see, after running the TestSuite, files like: TestSuite/results/dataN.diff showing a diff between the "oracle" dataValidatedN.txt and the dataN.txt file computed with the current (possibly buggy) version of the code. And that's it, one then would check the diffs for each test to make sure diffs are zero or reasonably small. (Stochastic tests, like those in SpinPhononFermion, need to be run with the same seed, of course.) Because code changes are done in small stages from code version A --> code version B, if A is valid but B is buggy, then we know the problem must be between A and B. Here the key words are "small changes" between A and B. So, one can easily find the problem in version B. Were we to make "big changes" between A and B then the TestSuite would be of no use, we'll just know that B is buggy but finding the problem wouldn't be easy. That's why code development must be done in small stages at all times (except when writing a code from scratch, of course) --------------------------------------------------------------------------------------------- TestSuite apparatus. Common files for the TestSuite (that is, common to all codes) are in PsimagLite/TestSuite This follows usual practice of putting common files for multiple codes in PsimagLite. Each code has a testsuite.pl script under its TestSuite directory (in SpinPhononFermion it's under v7/TestSuite/testsuite.pl) which should be a very small script. Code "hooks" are under spf/v7/TestSuite/TestSuiteSpf.pm for SpinPhononFermion and dmrgpp/TestSuite/TestSuiteDmrg.pm for DMRG++, etc for other codes in the future. The main features are: * hashing of executables, so they don't have to be recompiled unless necessary * powerful and extensible metalanguage for testing properties of results, not just raw data --------------------------------------------------------------------------------------------- How tests are added. Here I suppose we have an input file, the answers to the configure script, and the data that has been "blessed," is considered valid, and will constitute the oracle. The first thing is to give the test a number. Each test has a different number, let's assume it is N. Then one puts the input file in TestSuite/inputs/inputN.inp, one creates a file with the answers to the configure script (one answer per line) in file: TestSuite/inputs/modelN.spec, then one creates the processing file that contains commands in a metalanguage (developed by E.P.) that tell the TestSuite apparatus what to do. These instructions go in file: TestSuite/inputs/processingN.txt For SpinPhononFermion this will be mostly: spf observables where the label spf tells the TestSuite to run SpinPhononFermion, and the label observables, at least for now, just tells the TestSuite to diff with the oracle. The metalanguage makes this extensible, you can see these commands with: cat TestSuite/inputs/processingLibrary.txt [spf] Let $input = $inputsDir/input$testNum.inp Let $raw = $resultsDir/stderrAndOut$testNum.txt Execute runSpf($input,$raw) [observables] Let $result = $resultsDir/data$testNum Let $oracle = $oraclesDir/dataValidated$testNum Let $diff = $resultsDir/data$testNum.diff Diff $result $oracle > $diff One could process the raw data and get properties, and diff these properties, instead of the raw data. This is particularly important in DMRG++ because the data files are so large. You can see the flexibility of this processing scheme in DMRG++'s TestSuite: https://github.com/g1257/dmrgpp/blob/master/TestSuite/inputs/processingLibrary.txt The valid data file needs to be copied to: TestSuite/oracles/dataValidatedN.txt --------------------------------------------------------------------------------------------- Limitations and Future Work: * Each test could be run in parallel with trivial parallelization * MPI is not supported * smart diff could be improved PsimagLite-3.06/TestSuite/TestSuiteGlobals.pm000066400000000000000000000377441446452427400212570ustar00rootroot00000000000000#! /usr/bin/perl =pod // BEGIN LICENSE BLOCK /* Copyright (c) 2008-2011, UT-Battelle, LLC All rights reserved [DMRG++, Version 2.0.0] [by G.A., Oak Ridge National Laboratory] [TestSuite by E.P., Puerto Rico and ORNL] UT Battelle Open Source Software License 11242008 see file LICENSE for more details ********************************************************* DISCLAIMER THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS. ********************************************************* // END LICENSE BLOCK "Program testing can be a very effective way to show the presence of bugs, but it is hopelessly inadequate for showing their absence." -- Edsger Dijkstra =cut use strict; # use Cwd 'abs_path'; package TestSuiteGlobals; use Getopt::Long; use Digest::MD5 qw(md5 md5_hex md5_base64); my ($testDir, $srcDir,$inputsDir,$oraclesDir,$resultsDir,$specFile); sub init { $TestSuiteGlobals::testDir=`pwd`; chomp($TestSuiteGlobals::testDir); $TestSuiteGlobals::testDir.="/"; $TestSuiteGlobals::srcDir=$TestSuiteGlobals::testDir."../src/"; $TestSuiteGlobals::srcDir=$TestSuiteGlobals::testDir."../" unless (-r $TestSuiteGlobals::testDir."../src/"); $TestSuiteGlobals::inputsDir = $TestSuiteGlobals::testDir."inputs/"; $TestSuiteGlobals::oraclesDir = $TestSuiteGlobals::testDir."oracles/"; $TestSuiteGlobals::resultsDir = $TestSuiteGlobals::testDir."results/"; system("mkdir \"$TestSuiteGlobals::resultsDir\"") unless (-d "$TestSuiteGlobals::resultsDir"); } sub doMain { # Get command line options my $all = 0; my $lastTest; die $! if(!GetOptions("n=i" => \$TestSuiteGlobals::testNum, "l=i" => \$lastTest, "all" => \$all)); if (!$all && !defined($TestSuiteGlobals::testNum)) { $TestSuiteGlobals::testNum = selectTest(); } $TestSuiteGlobals::testNum = 0 if (!defined($TestSuiteGlobals::testNum)); if($TestSuiteGlobals::testNum < 0) { $TestSuiteGlobals::testNum = -$TestSuiteGlobals::testNum; } $lastTest = $TestSuiteGlobals::testNum if (!$all && !defined($lastTest)); runAllTests($TestSuiteGlobals::testNum,$lastTest); } #Hook routine for the 'gprof' command sub hookGprof { my ($analysis, $arg) = @_; my $err = chdir($TestSuiteGlobals::srcDir); die "Changing directory to $TestSuiteGlobals::srcDir: $!" if(!$err); eval("system(\"gprof $arg\") == 0 || die;"); if($@) { my $subr = (caller(0))[3]; die "$subr: $@"; } $err = chdir($TestSuiteGlobals::testDir); die "Changing directory to $TestSuiteGlobals::testDir: $!" if(!$err); # print "[$analysis]:Gprof command was successful.\n" if($verbose); } #Hook routine for the 'diff' command sub hookDiff { my ($analysis, $arg) = @_; #print STDERR "Diff args are *$arg*\n"; eval("system(\"diff $arg\");"); if($@) { my $subr = (caller(0))[3]; die "$subr: $@"; } } sub hookSmartDiff { my ($analysis, $arg) = @_; my @temp = split/ /,$arg; die "$0: hookSmartDiff $arg\n" unless (scalar(@temp) == 4); die "$0: hookSmartDiff $arg\n" unless ($temp[2] eq ">"); my ($file1,$file2,$ignore,$file3) = @temp; open(FILE1,"$file1") or die "$0: Cannot open $file1\n"; open(FILE2,"$file2") or die "$0: Cannot open $file2\n"; open(FOUT,">$file3") or die "$0: Cannot open > $file3\n"; my $eps = 1e-6; my $maxDiff = 0; while (1) { my $line1 = ; my $line2 = ; last if (!$line1 || !$line2); my @temp1 = split/=/,$line1; (scalar(@temp1) == 2) or next; my @temp2 = split/=/,$line2; (scalar(@temp2) == 2) or next; if ($temp1[0] ne $temp1[0]) { print FOUT "$0: Mismatch $line1 $line2"; } my $d = abs($temp1[1] - $temp2[1]); if ($d>$maxDiff) { $maxDiff = $d; } } if ($maxDiff > $eps) { print FOUT "$0: MaxDifference $maxDiff > $eps\n"; } if ( || ) { print FOUT "$0: $file1 and $file2 have different number of lines\n"; } close(FOUT); close(FILE1); close(FILE2); } #Hook routine for the 'grep' command sub hookGrep { my ($analysis, $arg) = @_; eval("system(\"grep $arg\") == 0 || die;"); if($@) { my $subr = (caller(0))[3]; die "$subr: $@ argument=$arg"; } # print "[$analysis]:Grep command was successful.\n" if($verbose); } #Returns the hash key sub getSpecKey { my $buffer = `cat ../TestSuite/inputs/$TestSuiteGlobals::specFile`; $buffer .= `cat ../src/Makefile`; $buffer .= `git rev-parse HEAD`; my $tmp = md5_hex($buffer); return substr($tmp,0,8); } #Displays available tests until user selects a valid one sub selectTest { my $available = getAvailableTests(); print "Type the number of the test you want to run.\n"; print "Available tests: $available\n"; print "Default is 0 (press ENTER): "; my $testNum = ; chomp($testNum); return $testNum; } #Extracts from the descriptions file all the available tests that can be run sub getAvailableTests { my $available = ""; my $descriptionFile = $TestSuiteGlobals::inputsDir."descriptions.txt"; open(FILE,$descriptionFile) || die "Opening $descriptionFile: $!"; while() { last if(/^\#TAGEND/); next if(/^\#TAGSTART/); if(/(^\d+)\)/) { $available .= "$1 "; } # print if($verbose); } close(FILE) || die "Closing $descriptionFile: $!"; my @testsArray = split(/ /,$available); my $temp; return $available; } #Runs a single test sub testSuite { my ($testNum)=@_; #$tempNum -= 100 if($testNum >= 100); my $procFile = $TestSuiteGlobals::inputsDir."processing$testNum.txt"; my $procLib = $TestSuiteGlobals::inputsDir."processingLibrary.txt"; if(-r $procLib) { if(-r "$procFile") { print "*******START OF TEST $testNum*******\n"; $TestSuiteGlobals::specFile = getSpecFile($procFile); my @analyses = extractAnalyses($procFile) ; (@analyses) ? (processing(@analyses, $procLib)) : (print "Test $testNum does not includes any processing analyses.\n"); print "*******END OF TEST ".$testNum."*******\n"; } else { die "Could not find $procFile: $!"; } } else { die "$!"; } } #Runs multiple tests by invoking the testSuite routine for each test sub runAllTests { my ($start,$lastTest) = @_; #All test numbers declared in @nonFunctionalTests will be skipped and not ran #test102 features wft+su2 which is currently broken #my @nonFunctionalTests = (); #41,42,60,102,104,105,106,107,108,109,110,111,124,125,141,142,160); my @testsList = split(/ /,getAvailableTests()); if(defined($lastTest)) { die ": Invalid tests range [$start,$lastTest].\n" if($lastTest < $start); print "Preparing to run all tests from Test $start to Test $lastTest.\n"; } else { $lastTest = $testsList[$#testsList]; print "Preparing to run all tests starting from Test $start to $lastTest ".($#testsList)."\n"; } for (my $i=0;$i<=$#testsList;$i++) { my $tn = $testsList[$i]; next if ($tn eq ""); next if ($tn<$start); my $inputFile = $TestSuiteGlobals::inputsDir."input$tn.inp"; next if (nonFunctionalTest($inputFile)); $TestSuiteGlobals::testNum = $tn; testSuite($TestSuiteGlobals::testNum); last if($tn == $lastTest); } } sub nonFunctionalTest { my ($specFile)=@_; open(FILESPEC,$specFile) or return 1; $_=; close(FILESPEC); chomp; return 1 if (/DISABLED/); return 0; } #Reads all analyses described in the processing file for a specific test sub extractAnalyses { my ($procFile) = @_; my @analyses; open(FILE, "<$procFile") || die "Opening $procFile: $!"; while() { chomp; last if($_ eq ""); next if(/^#/); push(@analyses, $_); } close (FILE) || die "Closing $procFile: $!"; return @analyses; } #Extracts the commands for each analysis of the current test, sends them to a key:value parser routine, #and then the commands are sent to an interpreter routine for execution sub processing { my $lib = pop(@_); my (@analyses) = @_; my %procHash; my @commands; print "Starting processing phase...\n"; foreach my $analysis(@analyses) { my @operations; open(LIB, "<$lib") || die "Opening $lib: $!"; while() { if(/^\[$analysis\]/i) { while() { chomp; last if($_ eq "" || /(^\[)*(\])/); next if(/^#/); push @operations, $_; } } } close(LIB) || die "Closing $lib: $!"; if(!@operations) { print ": Missing descriptions for [$analysis] analysis in $lib.\n"; } else { my @commands = keyValueParser(\@operations); if(!@commands) { print ": No runnable commands for [$analysis] analysis in $lib.>\n"; } else { $procHash{$analysis} = join(":", @commands); } } } die "No analysis was found for Test $TestSuiteGlobals::testNum.\n" if(!keys %procHash); #The following section of code resolves dependencies among the different analysis in the #processing file for the current test my %procCount; my %tmpHash = %procHash; my @dependencies; my $depFlag; my @depKeys; my $keyword = "CallOnce"; #Keyword that establishes dependencies in the processing library my $prevCount = 0; foreach my $analysis (keys %tmpHash) { $procCount{$analysis} = 0; } while($prevCount = keys %tmpHash) { foreach my $analysis( keys %tmpHash) { $depFlag = 0; @commands = split(/:/, $tmpHash{$analysis}); if(@dependencies = grep{/$keyword/} @commands) { @depKeys = grep{s/$keyword|\s+//g} @dependencies; foreach my $a(@depKeys) { if(!defined($procCount{$a})) { die "Unresolved dependency for analysis [$analysis]: inactive analysis [$a]. Verify the processing file for Test $TestSuiteGlobals::testNum or processing library.\n"; } elsif($procCount{$a} eq 0) { $depFlag = 1; } } if($depFlag) { next; } else { @commands = grep {!/$keyword/} @commands; } } die "No runable command in library for [$analysis] analysis.\n" if(!@commands); commandsInterpreter(@commands, $analysis); $procCount{$analysis}++; delete $tmpHash{$analysis}; } die "Unresolved processing dependencies in $lib.\n" if($prevCount == keys %tmpHash); } print "Ending processing phase...\n"; } #Resolves the variables in the commands for each analysis of the current test sub keyValueParser { my ($opsRef) = @_; my @tmpKV; my $keyword = "Let"; #Keyword that marks key:value pairs used in the parsing action my %tmpHash; my @commands; my %varHash; #Only variables found in @varArray can be used in the processing library for substitution purposes my $srcDir = $TestSuiteGlobals::srcDir; my $testNum = $TestSuiteGlobals::testNum; my $inputsDir = $TestSuiteGlobals::inputsDir; my $oraclesDir= $TestSuiteGlobals::oraclesDir; my $resultsDir = $TestSuiteGlobals::resultsDir; my @varArray = ("\$executable", "\$srcDir", "\$inputsDir", "\$resultsDir", "\$oraclesDir", "\$testNum"); #Variables in @nonSubsArray will not be resolved during the parsing, instead #they are resolved prior to executing the command my @nonSubsArray = ("\$executable"); foreach (@varArray) { my $tmp = "\\$_"; if(grep {/$tmp/} @nonSubsArray) { $varHash{$_} = $_; } else { $varHash{$_} = eval($_); } } #print "RESULTSDIR=$resultsDir ORACLESDIR=$oraclesDir\n"; if(@tmpKV = grep {/^$keyword/} @{$opsRef}) { @{$opsRef} = grep {!/^$keyword/} @{$opsRef}; grep {s/(^$keyword\s+)//g} @tmpKV; foreach my $keyval (@tmpKV) { my @t = split(/ = /, $keyval); $tmpHash{$t[0]} = $t[1]; } } foreach my $comm (@{$opsRef}) { if(@tmpKV) { grep {s/(\$\w+)/$tmpHash{$1}/g} $comm; #grep {s/(\$\w+)(\s+)([^<>])/$varHash{$1}$3/g} $comm; grep {s/(\$\w+)/$varHash{$1}/g} $comm; } push @commands, $comm; #print STDERR "COMM $comm\n"; } return @commands; } #Executes commands from the processing library by hooking the command to its routine sub commandsInterpreter { my $analysis = pop(@_); my (@commands) = @_; #Keywords in @metaLang are used to hook a command with its routine #Routines, in conjunction with meta language keywords, can be added to expand the runable commands in the processing library #The commands will be executed following the order below from left to right my @metaLang = ("Grep", "Execute", "Gprof", "CombineContinuedFraction","ComputeContinuedFraction", "MettsAverage","TimeEvolution","Diff","Xmgrace","SmartDiff"); my @arrangeCommands; foreach my $word(@metaLang) { if(my @tmpComm = grep {/^$word/} @commands) { @commands = grep {!/^$word/} @commands; foreach my $comm (@tmpComm) { push @arrangeCommands, $comm; } } } die "Unknown commands in analysis [$analysis]: @commands\n" if(@commands); foreach my $arg (@arrangeCommands) { my @tmpFunc = $arg =~ /^(\w+)/; $arg =~ s/^\s*(\w+)\s*//; eval("hook$tmpFunc[0](\$analysis,\$arg);"); if($@) { eval("TestSuiteHooks::hook$tmpFunc[0](\$analysis,\$arg);"); } if($@) { eval("TestSuiteGlobals::hook$tmpFunc[0](\$analysis,\$arg);"); } if ($@) { eval("hook$tmpFunc[0](\$analysis,\$arg);"); } if($@) { my $subr = (caller(0))[3]; die "$subr: $@"; } } } #Subroutine for the 'Execute' keyword #'Execute' is used when the user defines custom routines sub hookExecute { my ($analysis, $arg) = @_; $arg =~ s/(\()/$1"/g; $arg =~ s/(\s*)(,)(\s*)/"$2"/g; $arg =~ s/(\))/"$1/g; $arg = "TestSuiteHooks::$arg"; #print "About to eval $arg;\n"; eval("$arg;"); if($@) { my $subr = (caller(0))[3]; die "$subr: $@"; } # print "[$analysis]:Execute command was successful.\n" if($verbose); } sub getLabel { my ($file,$label,$dieIfNotFound)=@_; defined($dieIfNotFound) or $dieIfNotFound = 1; open(FILELABEL,$file) or die "$0: Could not open $file: $!\n"; my $value; while() { chomp; if (/$label(.*$)/) { $value=$1; last; } } close(FILELABEL); if ($dieIfNotFound and !defined($value)) { die "$0: Label $label not found in file $file\n"; } return $value; } sub getSpecFile { my ($file) = @_; my $value = getLabel($file,"CONFIG_MAKE=",0); return "Config.make" if (!defined($value)); return $value; } sub hookComputeContinuedFraction { my ($analysis, $arg) = @_; my @temp=split/ /,$arg; die "$0: Error in hookComputeContinuedFraction with arg=$arg\n" if (scalar(@temp)<2); my $label = getLabel($temp[0],"#ContinuedFraction="); $arg=""; for (my $i=1;$i/); $arg .= $temp[$i]." "; } print STDERR "Executing ./continuedFractionCollection $arg\n"; system("./continuedFractionCollection $arg"); } sub hookCombineContinuedFraction { my ($analysis, $arg) = @_; print STDERR "Executing ./combineContinuedFraction $arg\n"; system("./combineContinuedFraction $arg"); } sub hookMettsAverage { my ($analysis, $arg) = @_; my @temp=split/ /,$arg; die "$0: Error in hookMettsAverage with arg=$arg\n" if (scalar(@temp)<3); my $executable = $temp[0]; $executable=~s/\\s/ /g; my $label = getLabel($temp[1],"BetaDividedByTwo="); $arg=""; for (my $i=2;$i/ || $temp[$i]=~/\' #ci getTimeObservablesInSitu 4 '' #ci getTimeObservablesInSitu 5 '' #ci getTimeObservablesInSitu 2 '' #ci getTimeObservablesInSitu 4 '' #ci getTimeObservablesInSitu 5 '' \end{verbatim} \end{tiny} Inputs 340 from the TestSuite follows. \begin{tiny} \begin{verbatim} ##1.0 TotalNumberOfSites=8; Orbitals=2; NumberOfTerms=3; gt0={ # gt means geometry term DegreesOfFreedom=Orbitals; GeometryKind="ladderx"; GeometryOptions="ConstantValues"; LadderLeg=2; dir0:Connectors = [ # x-dir [-0.058, 0], [0, -0.2196]]; dir1:Connectors = [ # y-dir [-0.2196, 0], [0, -0.058]]; dir2:Connectors = [ # x+y [0.20828, 0.079], [0.079, 0.20828]]; dir3:Connectors = [ # x-y [0.20828, -0.079] [-0.079, 0.20828]]; }; gt1={ DegreesOfFreedom=1; GeometryKind="ladderx"; GeometryOptions="ConstantValues"; LadderLeg=2; dir0:Connectors = [0.1]; dir1:Connectors = [0.1]; dir2:Connectors = [0.02]; dir3:Connectors = [0.02]; }; gt2={ # gt means geometry term DegreesOfFreedom=Orbitals; GeometryKind="ladderx"; GeometryOptions="ConstantValues"; LadderLeg=2; dir0:Connectors = [ # x-dir [-0.058, 0], [0, -0.2196]]; dir1:Connectors = [ # y-dir [-0.2196, 0], [0, -0.058]]; dir2:Connectors = [ # x+y [0.20828, 0.079], [0.079, 0.20828]]; dir3:Connectors = [ # x-y [0.20828, -0.079] [-0.079, 0.20828]]; }; hubbardU = [0.0, 0.0, 0.0, 0.0]; potentialV = [0, ...32]; Model="FeAsBasedScExtended"; FeAsMode="INT_PAPER33"; SolverOptions="none"; Version="61289987cdd32b8485213ac0415baf4e9cd16432"; OutputFile="data340.txt"; InfiniteLoopKeptStates=60; FiniteLoops = [ [ 3, 100, 0], [-3, 100, 0], [-3, 100, 0], [ 3, 100, 0]]; # note the abbreviation here TargetElectronsUp=8; TargetElectronsDown=TargetElectronsUp; \end{verbatim} \end{tiny} \end{document} PsimagLite-3.06/doc/PsimagLiteLogo.png000066400000000000000000002010621446452427400176470ustar00rootroot00000000000000‰PNG  IHDRÊÅ W pHYs  šœ IDATxÚì½y´­g]&ø<ïû {8ós3‘H BH0Èd¥qBuQ¥ÝÚ–¥vu÷?µºª,J˲´UT¤,mA *ÌCHÈp“äf¸Ã¹÷œ=Ãû>ýÇ7ïsKÓkUWy³Vrsï>{ïïû~ãó{~ÏKIøïóW–"Ëáäá=œCžÃåȼCq[Hœ9­3§¹»ƒÑ³)’.Wî˜.4Ÿc6ã|†ù‹æ % ¤ ÓTyçè=¼‡AÅÿË¿¯þK–_À« `(ŒÇèõÐë«ßGÀA_ý{}D‘¬E²×ÇpEkëXßà9G`my½ÆÀX6@ÀZ0A€ Dü÷iüoÕ4òñGuæ ÓF#œ:‰S'´sIBB'c,Hy,c²À|ŽÅ‹²TÎCIkaX#c@²0J„”6KSüH,>£xYe⨠ÿ+] ýçX{ƒÊ·¬I‹I*¡¨òè! ÎÑ;åŽrh ¬E£×C€^½X&@`÷Ðëi0¤¬QÀ­ý8pûöc0D¿ýuÞùüø¯ñ×ém|å<ò&{˜GïÃC÷c ”·§HpÎÉ9:ïདྷ”³)\Žá Žœ‡sÏÓÚ:×7tÁ…ÜØ„µØÜ‡ýÐïcm ûüƒœí×d¬Ï|Šg¶uÏ]¼ãvLF C W–#Mç`,,ˇI£æ –ÿÔ–VœlF•JœÝt:†»\“tÜeù÷uÙìñ’V.HÖoÖ|Ÿ®5£ûÅêÎAÉæÒÛ_£~MÚ‘¾õUD¡vk±{¥­‹Ps{;u\™ÿªÛ]‡H”H ÞË{#Å1IRYÆsÏÃÕÏѹçãÈy¼î†³gÜÿ¦@Ât‚<ÇlŠÅÞë“Í'ÇÑ{uë¹³£Õ5®¬ÀX¢¤$–ÕmehÙLi Ù­ Îa[ñ½)¦‹*šmãÃRåP?÷vØ/ •*T’c´m]•×álVX…^ToPtÝwjFõµ¡ão]¬¾º gùÐæ:N¡ömiݶO6N\Ý·ê®—Õ šŒÑýê̓¡’pNiJï‘eí0ItÁSø¼çãàa=ír>ë*â[û†0æÿŸpû­:½Í¯Ýc#Ëqú¤æsœx‚§OËöû2–ÖÈEeÚ-˜›¬e+o=´Œ¼zXE–V7<–6Ô*’»Åù^-Š™–ù¶jþn2aËÄÕ|›"8Ö=À¥+hÒ ªÀ^ÙÒò%£àµçeíJ¬¼Ajw)/ß¾ü¶‹¶²¥Ê@νù¬ùÓ¥‡²Ô…´¬ªù¶­V|0 Àyø\^ÈR,´ϸBßþF¢\|©®¼š½Á• AÂÇ?Š£÷苟Å?Ç ÒÚ*M‰²-’³=¥,¼T‹wó3—+¥€ÓŠÜKmj§`Q«¼îš=»zÍë<´7@6ñ·*aê7QÇV–­G­f¸¤Õ·o²B]¬/ÙúRN¨qV¢ýËíÅ’ïmšÀ NÊ@» _NnŸW“ê ÖMÿ¾üå¯;®Ú´v\¥{–Ú·ê­cqÙ¥xý1™Êš@å %€(Â|Ž÷þF»(f{ʹ³L šŽ³JùAÝìnÐ$„ªjeÃ=%e;×-uôèdÖªòæ°‚šTÝlÖ¥SmÔ†ÛúŽàÙ¿OË%ÐßÚÏýI(èKƒ#%,¹Œ§N"Žñâ›ðïÞsÖbéop€ç=ƒ!‚ 4¶îg·§knrÇ+ºy´¾ñÞ#Ï1™(˜ç F°Vðu¨ ÿ&¬½2¸=M‚º~DžeÈE.Á޹î:—¶HôƒïàEOÅxc䬥s2„ó4„±àr¬­áýˆ£÷¦m­Kƒ±â»Ö";8USíqéîÄMaWÇ×%À·SÛ7ÐÔÙ‚ðÒÕí§Ûš{À‚³ NݱÊY†Knô÷.â[ÖÖv’¢xô>/j¹Ÿ–ꊆ‡æ1«5ªk0Ðæ›“M*TÍÆjÿ“9‰j Žv¿øÚg}ýÙà«_A`ØéïË;Ëæ+³5jü„Šœñ3ÿDç_§’x,1 E2z=x'kqÙÓyõ5r¹Ð <‚š1£Zø’*ã!¼£c…ˆböc­­ã©—ñêkpÓËqà66d²Œ¬°öúÑ”SŒö`³zœaÀg\AyCIÖÂy¸œyNçª^ ð``°¶^fÀ<çµ×*MšR­vÏÊ{Õuˆ†Xá?j:  [ÐBöR=J@›’T†_v£Gë5êäõÊÈ«á¤Ø7$T¤æv”« ;”àwÙ;«è÷˜;dòÎÅ Jk'u«ú޶ÐÆ1>þѳ¾þl%ÐÑ{« ¶`8VóV]··ÂfSê øî·b°Êz GïÃG?‚Íò1•¼ÏVÜïñÌ+1Ú@ŸÃ„…¡”‰Ã×Í,D!I™ž†µá…µu†ð^Ý*¾JøeÿÝÂjšª¸Ûב^u¶m‘Ù¼ºlôÚYSfpHR¥½% i]}Ö¥n{à¸L@ª4~]¹·÷r—^ÊÃGpøfsŽG˜/tûmO°ºBùÂvԮ̞„ò¿ Äw‡>E¨ý[9@±ÒܽÜdk\Ô褡y˜Œa¿‡Ë¯@–—î`,½DÁXÖl˜}°»tYŠW|'~ýW±ºZ~ñH4ØØäÚŽ?W¾ ëë¸û^NG¸÷ü±wakKÎÃeØ:€ €÷eŒ{ CîœAhÿ:_Œ÷ü‡ÃÊ|Úe:C Á4 ­’LåJ†e§[”àÞ@ІyVl® M;ਫ¹V¨û©½|ºúKª5Xå’GÔ@caäƒP‡²¶kçv·Ú rl­ng ®ß”w4Ëpð ßþ àœ¼XË<ÇM/׃Gù¾ÿƒ~ÓÅ—ýØ“Õ4]šJ™4\å-_À5ÏÿV0ëÄq6M[Ñ»¥gý@©%¾‡óÌ2{VWùí/FÁXx<¥$y|A 0—f œÓÖ&bá²§óȹzîµ\]…—¼gcû¤Ò—?‹Þ•!$KX°G60«¤²hé÷¹H°ïvÎ0î)ÏqÑSñê×ò¯>¢0¨MÍ2@wBGˆcÈdhD¦2Ö"çkD’°×‡|µ Ót%%…•\ŽÁ%^ÐôÃ56ÛåuVI•ìNlPÔáJ\2I¶(®{©¤hÏÀÎ2|®ú…VxeS(Õ‰J­ÕlÆW½Ï>F£º« —òÖh>åùâŸüS|ðOyÿýTðíß·Zži6øL} ´F£¿uÈs.æUz*¾Û¸v?ÖÿªïNšrkÞñÃÈsÚ@±?ÐdR iÊÉ"œ£QÙ=dÛ¬ý<×›ßÊó.PÒ¦)F#… 5š3îa0ätŠ<Ãê  ű²Œ½A‰Æ”ø¸Dr±D뛡„iŽç<'ã+·U€fÙéÔСjPd¾@ÔC–’R*s®œù×$ä(F`>g•¨WýïÎHëy\Æ[hÙû°"O¶±òfÐÂjP^Ñ"š_T9î¯ÜCµk@Hµ–ØZÑ¡Œ²5ŠîâÔ ŽçÿôSØ·Oã1ƒ°¼R—K‚µ%"â½ðÝoÕïþ6Nœ$Ÿ¤˜ìÒ¢Ê'©6 ÀXÜú%¼ø¦oÕvqìá¦Å¬Ð6‹£î‚¥æþä9_pƒþÑ?–Ä T3wØÝ¥s*zË8ÆÖ’oÊÆ ŽiõûÜϸ¢áÈ3õ ©`D Éc8@š!I‘¥ÜÜÕU@ð¾|P¦r†â 1Â;Ê3<ï:Ä1ÚPI®®qWÀ½WÖÀ` ««°–%yÕnd}‹žÅУ‡¿ñ¸„ßši›Z­+ëMnì\®,—µò9\_ôU¯ÂPêeÓC´3CíÊTS~¼ÈnAUmM€Hu¹°õÔøR§/oê ŸëÛ¾ ‡)wÅ6™HÊÃÅR^yÓ$D¾ë'°±çžœêX¢z«´_ÖI†|ìÑ¿M Ìçê[PrةڷÚ^а4OôßÉk®åtZbýAõh à+ˆ›ØØ‡3§à%Cìõ`C<} V8°#£^y§j4Sìõ ÀZ]ãhG{ý²QnÂ-årZ CI •,e¤Õ¾ýÜÚãO´Ç9\âý’|ü1L§2†yÊ•¡²TIªŒ/] ‚Âs}|ý.Dq=dRS íå{.g’è†xä<ÖÖ0 À-·àånPYpydyáá%é° ê— g :ÖKõ ½‡-¿ïxw™oõHç,t;gQ×½iZÆ«ñ9ƒ Ùñ7Tš2Œ4™ò­oÿÿ•'oÖ™Uá¥3Ë sð~iÇ`Üõ5õzdw`‚³àp-LºñF<ç¹ZÌa Ò MÔ·eüö媆¼‰Á &#Ê"îÉ–Æ\Ù@:/~D† cÈÃ@Þ# ¬œkKïà<«8f!Ï0"MaŒ’E±šÄ1Ú•÷$e®®aû$`i-Cȃ¥›n ð‡ïãÿ(f3$)m$Õˆ§z± ‘,е5…Œ·ûŒ©=«e‹Á#GðïàlZSýtà œã¥—!Ëõ?À€µÊsÆ1WWpÕ³á¥ñˆ_ø|)èÀ’ñ¤ª„QËêˇmÖ`‡•×âc‰ Þ,uÀ¥šß¶ð-ZÝ |Ù ÈÓDT–Ó–e`‘.ØëcuO½DÞ_Gžø¿EZ`3iQ•l¥“Ç9c}ý›:Àí·"Œ–øßí‘iµwRÛa ¯!\cAÊ{ÈËÖÖ4è 4×í)f“rk. Eï0\EIÆ"†PÑÔ‚Þ¡ô 5` /Vár€ê ç$E˜Íd-§S•»”†ÂXqYŠ4å5×àî;Ùë«»ÞáDØ>¨»ïÂS.ÆúNoseÉ„rGceHÀùÅ(•÷þT«2lmòÂs‡—Ý„ë^€ÉDÖ²(ŽmÀ<‡1JÈó-߃?ùcM'|ÖUºêjÄgs@4¯#žxœ·EwßÍãO аDBnNjí(7í.ªÝÌoÉùAÕ€ÔßjÂPa¥Þëü Ù5[TE³à è!°HÂNaHÆ*ÏF8ï<>p¿àÿþ> J¦c‰zÉ@i†²ûf=Àém6#œKª,¬TÏ‚!M§xÅ+Õë ¦œs‘2†Y&S³¼Cº¨Æ›‚€á ä)‚PDzÎÉX†!‚€¬žÛ¼~€^*H—Þ©×+ÈÉ XðÒŒ- jÞse ýa6Ș¢3+˜!²RË-׊YvOaȼŸò]vçsîì*ϵH‘gØÞVã…7òø>]tq [ÅTQ@õ>hk "5d–e2o |·.¥ªfár:çI2D*ÛsЦ,5 ´,îÁå9³Œ.½ ÞccOÎZ"kÈ zCµê|ôŒGßÊ>ñ1A ¸±Šf­ö_Í]9âYW1Ïé]©µT,¹¥‹†ô[üÎS&᪼„"•e°!­¡ó £*ršòß$‚@ÅO•Îài!¬¥äðNÉ„X[Ãú&ÖÖˆ#D1=ıVVaZ$lµz­B¡Ü¤¯†Q’wøùŸE–3K´X`:QÁz˜ÏKÊN–3°°Vû0n¾¶ñW0a—§Tx× —¾ŒÎ6€÷ Q_V×i CFqQAÒç$àkI`1‡1øÁÆæ¼W‰64³¶èYŽÚkÄj¸ÅðWmEëÑW” Ô‚DÀZc5”5® ŠË<`+‚G%ž¤d€ÖJÒdÌ^OÆ`gçÉ[¯f!d /®,v:A–}+8y¢ÎG*éV {·Y.JXyœ{œ È6 hŒ¼0Ú)c’V×¹¶Ž¸ÁPýC¬oÈ{xÇ0dž TVu”‘10VÖÊX,0Õ\ËXH°ÂÅw †rŽy¦4E–!Ë! ͘e°6¶¸²Â¯Þ®0êÙ"®´W”A­­áÝ¿ˆ~ÉçžÇ^½~¡3Å8Æp€›oÆ/½›Ÿù4Ö×Ú™—­I›¤ÅoÿŒF2Tb•¦–ç’SA8è÷†ˆb9‡0B"ŒeCX9䙜/oÅt¢wýbÁÞm¸Dl1S*Î\•†‹¾¹Æ÷ZË‹õEEpl†flwÒͶ(‰ñý>Œ•öÀ…ÖÕâ&Qðð^y—SvvhÍ“8 ÞÛáW•ƒ2ŠðÄãßÚ>¥õ ÂwX~­¸E^­ÆÄƒ~5Ï¡T‚"EJS8WÆòéDqÌ (IYKÓ‰–… ÷B@%hd ä /™rúO@qÄ0RQNXKcDCïÐï†é¢¨,Z B´eä2Ô`@y W¸» g]ÖfMê®î5º÷n~í­¬àêgsÿA\û|½÷=œÏuÏÝÜØ(zŒÒaº‹ç5Û¥–DáÁCØÚB’Ò°†Èó²»’˜e°qOaDÞ#ŠELÈÒêb!ˆa ‰„ÃdŒ×½ïýmäY¡hFÇs5’æÒBfá­U›¢jÌÖô¾u%T%R1˜Ž†…˜Í0;AÚÒ“Œ‘÷¬+r9yÐ pyòúw-€Ôt7U¢kæ'B볟â 7þÍàsŸæpXvÁešdkúWÖZÞéÀAhn¡¿W¼À’^´–³)Y+ï.ƒ<¬åb$ÑÊ ¦SÄ1< {-o¨Ëé=l€ÀÔ—HaHXK0ŠDƒdÁr>•S å|VdõªðõÈ28'çðöïWÜ+jâÖ¾.‚kÖb·'Œ"& ?ý)ý‡÷ã]ïäÑ£xìQ¬oªÊia&BGz­B¤)^üL¦òa„ ¨ìCô¾Œ-6@Óˆû"XÈ•p¶]^F‚,…$CX cpð66‹°^Oî+Ö¦Z#µ:äׄ6o¯-ìU4[e Ìn¡Q^fQ;îìòäqHÊ3ÑÈ0ÕìΫ#[ûcâzìž U’.vÕ&yÕX Ö,'ß¼˜MÔ ¤‚$-CÅDKÒÂXœ8®šãœ‡<|awFYŠ3§ªTë彯#ä9²LA€À"I¸2DšœƒËKž\áˆq½X^4$ŠçíçÅ2†Yª¢‚Šû(ÄhsW>W •\³;éóœÃüèsw·ÍwWÓ7Qmöi›‚F"Š8`ÿY c›lÙDjT¤†2WåÚ²–ÃÊ3¹¼4ú0€((*7°ƒ$äeƒ²fklœ»Âç%)KqÍs±Xpï ¸Eºß[ÉTzpjVÊÑPðX%¨&T¨MåNoãÄqL3¦ Ú@½>‚HÞÁ |cJQ^8zþ~\¸.,º“QÉUIA/J@à¶[¾™èóŸeÖŒªä4Ù [fQ€’ã ‚./×d«dy÷‹‚~û¤¼Çî|Žý˜.ðø£<³­ím;†|yŽ<§1"µ¹…(DÑZÉ!M™å ƒ2 ‹(*Æ^LãrmC`¤a鯯ŠF \Ž,C¯Ïd&c„Üܧë®Sýp«°PB%,FKikÊ]¹Ð0Çš¡ šæßDv¨ø5$ch:Ç$m#²q4² m¼ü!F±¼ƒ¨<¥sˆ" WeƒÒ0Hô4– h8áèQ2D1skVoK”Ú"ƬWe¬ÅWoû¦=Àw ŒŠ},).ÕâSÕÞ›Ã{ïf)Y”lBYÀy6€Ë„œLa€3N@ÜÃoÿ†¼¸sZó~öç9ieaȨ¯$Áá#xä!Ð÷,Ä…Œ(‹(†s°¦œ¢Ë8JHr®ÜcZ¢{Ï$÷ŠzLÙ€½^ø"Þz+î2 @SŠ_>Ï¿ûöÃZNÆØÝÅm·à±GÑgCÙµ$HÒìV3i:ƒsLÇ "¬¯c:EPM `z!O@+ùÔ¬±n mŸ*™ªa$ïaظœGžáð^x!¢.×Cñ‘G@ ×ëòDÉ%Õ®e-u™_ènéÛ§ð§ÿoý^Mg0Þ#÷ BÄq‰Mf)¼G`‘yô"¼û×…µ¥þHAËZÆmò`3¤k ¬ŠÙå7qò¼µm‡=›t¬ùþEQ§•U¾ï½xûp2†<®»‘÷Þ…ÉÆÈZ01”+ÊyV–ãk_Âöv¡’‡g\ÁMœÙÆh‡[ûX:§“'(-CÁ8  PD”éÖJžAˆ(™mìœÁ%á…$¡1’/â+äJ£^$ÈÈ+ñ #\| = ïyîùZY¡wE¬ˆÝã1Æ÷¼]‡s>CžÃ ºàB^÷~ásúØG[(@5 —§1h/ ¨ä%”€‰„ ¼áM¸ä28Ìéúýâ^A¾Œº‹n„eU™&€¥!²4u»Qö éὂ€É‚ûïS>®<Óùòߥ0,N* €—}‡fS|ñ üô§ÍÔ´Å£^Ú¼¬Õ!Ø!TÌÑŠÔ§¸Ç»¿Ž?ûÞô ÐÀó9H-#¨­ýœMa,Q ›c IDAT¬Ç¯ÿ{Å1åZÊ+²êߪåmö»ÚF]eÊVÿ.nlꎯðÊ«ÏæÛ§*]Îeý¶Œšå @B`qÏÝ|è:x€^úÌ'êY Jó rô’Ëa­ óLŸüDy»#¾ñ»0ƒ†Ó V×°X ßG’t°¬vÐ`6Ež" •ç$ Ý67pêŒU2£w' ’¤¼©…Úž÷eJòŽ> ’Æ" ñÌ+õå/2 ";C=ç|Û8p˜ÉÎae ÞÃešÍérL&xÎsyù3ñ[ÿæs,\[Ã%—2 qùºëNdOŸÖÉH3f‰z}z4Å¥—áÅ/ѹçc¼âU¼äRìîÐùbA‡€&cË—¼ ?•Ÿÿî¹»œ"·ùÛT]µÖ¦öĸÙ©K&ÖÝÏ¿€É×^§‹žÂ P’00Ê<ŠíŽ(ä]wá¯?ªé”ÖÖlšš«Íoµ"ÌÖ®~ÓN°Mx%:Òcí |(Œxÿ}8»윑ó-µªþÙÚˆ`G¥¼ú~ø{ü©ÿIÊÀByR.§)„U Dðžûöã‡Þ`e•“qƒ¡ ˆz "e)'c-ðcïÂÏþ4_x£^ú2Ú@Qˆ¸Ïg^ AiÂÉDY†O~œý1>Œ·½ÉŽv!/“]VÈ £¯0™SàÅ^$z/ Wtâqf™ÚZºÅSõªpF«^Æè ŸåêªrÇð#?Š4Åh‚”£@ŠiJ{˜ŽqνöõüãàñÇŠ(4¤ÐŠzXódÙ”¨_;\ø2ßű÷% ^÷zÄÖ70b:Á—¿„;¿†Ckjt ÙêòU÷ªž¨í¶èÊK+vèJ¨]Áj´Ë³—@iʚȾ¤YåIÕ‹Ï­EgHLSü›wþ¸Â f©Œa"M!‘,tú4ç·Ç ‘Dk<‚÷”“Çö)Yï}ŸùÞ÷•½sòŽYVïT<ÓS乊ÀX(Ðh—E»Çú¾ À8†¯6l º€4Uq¼J˜0ϰ±¥Ù„o~«ž÷<Î ¹²ŠÀ©,3VV¹˜ã¯Âw¾†ð{8rD`á™’èry èqûå†Cf™F;$ÏÙ”½žÂq=Bh1*!2 GM+* .ÚÜâWnC2Ïð–ïÕbAçÄ›¶H†a±·dõ#ïäOÿ$V×Xï±ËÒ/»sµà£öͩљbgHúÃ߇÷È3æA€~ŸQ$kê–¨˵–âξÆÎ@mY4†ìh ¡)ýU7õå@#ŠõùOãûøl(Уh1W#"XõÒmñ:Õem÷[X«4Á/¿þxÛ­HS ‡ #ͧ˜Œð™›ùïã¯ÿªò iR Â( uü8 C'™.0›!ŠD M´˜)KiYË,£sZÌ‘&˜ÏéÀAœ8ÇŽÁZžÞ† 8›"Fryáë%ŠmXŒÌÀÚn—µD&R“1^óZÆ‘ò qOÞ) 9XQ–±á=VV!èô) ºéœL0"îÉ{,HæHæJSd©úd™æsüøOt0Xƒ âp›ûè=§ÐÂå´aÅyä|¬®—Mµ÷”gBä)hà=U)6¢ØÆŠ]ïAp6Ó±‡ê%7amÞ!ŠØšrè…¢•J~”<Æc¼ë'pêdFT:ÐÒXQÝ;¯$A–!Ï`Z´ø%¤µXñ¾¡ýûµ¾®(l«L ÛL´7H[mÛÚÙRdkr!t¤¢j—¬%ð›ò.øÀ} ºs†Y^_0ë§=+%Ú„“®¢‘µøä'0_(Œ˜åìxä<íŽñøãzìQ{>Ÿy•n|16· ´Žƒ!ÿó'Øë‘DšâÅ/g¯ÇɘÞÝ:%LFLÁ#YpÐ/Jsåƒ_ü¼Cœ8BQ —i±`ž1*†Ð%7É BžË;ôû™g’à=Çyèêk°X ?Ô`ȵuôW` ð<ЍßÃ|NqŒ^¢Éû*Šárz‡4…÷2ý¾Czþ€½¾¦#<ÉBQ¬~뛈b„‹)mä¹ ‘$*>Öjç ‚Îaç4h¸²¢^¿Â& Z`ôû BBèqó'¹;BâŠgÂ;D1¬jДƒ¤ ,pCkEØÜÒ•W•ÜFI§¥\¢JÁ>Ï8ç\¾ô&]Ÿý<<Õ¨Ò7P[ýAI‡dM¬v@›ñ„*\µ™É´v´›tÔTþ--®ŠTÆ3ÔS©ö!jdº$þ (PÅ«‹©ÖAƒzôÓRý '#\~~îŸÉ;d’fS‘¼è©zþõœNX-HS½ñÍ÷|æSÙë·/kí&V²mÛ©85u]µm}·†©Xñj}©£†Öáu¨«Oº,F^$CìœÁÆærЃ÷Ãu˜ÐjÈUܳ)Ú: Ó©¾û­zã›4Ÿ!Ié½¼È^«kÜÙ)Ï>Ø9ƒé?„0Æ«_Ç_ø?pÞùúÐ_ÀX#—# K¾TÓ9ž{>² 6wr“ ¢˜a$‹.¼"ôÈÆۛò’Hcd ¹\¥œµ \Ž,åýGX 8ÿ|ÄÄ1—÷ZÌ‘$”&L0–ޱ׃ËÒ¬¬b¸Š ¬®a0ÄpƒAIô`ZUª Ð"Kuà0ÈiZ­#‰ â>¤ ’ ÒE1óBšá½¿«Ûnáïþæ ǤÚ@ƒ!²Ó)’9Ç;Ê2ͧˆ#Üz ?ð ‘eºü H @Ê9HôM8¬¶ø>‡¹ÃtŒÉ%û¶ž¥6¡™LÞùc¼ô©L˜Œáò¬_êºàïÔµ×b1/çÇöÈfVö]Vëb e)×ûUÍãU ¬Ô’Â’H›Î"@ÜZçl 8TÖ’ß çqzû,%}D4ícë Ê¤Õ²¥-U¾ó‘#¼ìéåm.fû4C­¬b<’|qª—VÖØòðll*ì!îãŸýs¾æuˆb„!ŒU–j4bš`wYŠûîƒ1(´ƒz}ò §Nðô †:÷í? ÙÖ*ËJý¢8 ·¤mÒÀ†A2ÇlÂ8ÆG?Â0b(ás,æ˜O)1Ï …5‚ʼCb>W•®¿¶Ž J: yŽ8fÁ0„÷t966´¹‰0bî°º¦(RÜ—µ BJ^΃F†˜M°˜Ë{J¸ø¼öu4IŠûnÜ‹9ã˜ÅÉQÖ(ê#ŽéÅÙT_þ²ÞÿûŠâ’wdŒl€,ƒwL“’]Rm Wd1Á ? c ÀZœ{zýÖr´*1=оýüÞ·a<©j AsLSø V¸ñÅ8|ZkËj«ÚayŸ€Ðq[£¥Ø&#:䃶BQC3W— Qè{U¹ZsÉÈ®™’J].²¬Kî,„-g”6•fxíëK±¢€Y¥X?ˆ4E`Ùë)ËDF˜ÍeÊÒÒèg3Ð2M´ºJ:GÛ'1ªßGÔGc±ÀÝ]¤ ØÓqÑ•je…ÇŽñ'þg­­–Ä…bùº×ƒsR„4QA¯/ðŸ(Â|¦Ù”‹¹V×ùÀ}8z¯z=L&d-³y®Í}åÕÚôY.yÆ=†!ЧÅaÄáÓi±¿‰,CÒç¥\}q:‰Ge¯§•UŽGêõ`EÃ` ³^0d1Þö¾ü®»ž'Nà¶[Eò~û÷ãœ#8ï|ìßqŒ[¾Œ,Çý÷a2áêZGV#K‘,ÀžâcÀÚI+Küb!ˈÞ#°%H²³S QñU0Ïqý ÊR†AQ¶`HÓ¢§ ðòWà=¿É••6&Ù=^v‰]¹W³T-kYuÛ‚4Z>k¦£‘„î1R­™ áÉ“¸ôé{à‘‡Eƒz+¤¾†– tsžaëÜ ®®êȹL’æX/ö 7h:e¯¯0D’ÀZ¦ Iø\9„èõ4&çs!y++è÷é&X«$À<‰<ƒ $OîîêÕ¯e–Ãûbûd±œPŽ1†+œŒ1"K•g,„0?Š_ü:|˜E€œÏ±¾PýA2™#à½âm^TDL攥œqŒéD6`Hž¼C£HDÞÑ@$m sŽàÔ)ƼgžËzWnfgä¹ú,fàrÎfzýwñö¯Pq4ÂîwÝY¬Þ!ê•_¿8˜£"ñ—UÑps ?€€,¦éjÊ Ôg×÷‡ÌÒšSyÖw#v"aˆg]‰,“÷…¢M€Bù0ˆ` ³¬¬Z/{:žrO/˼Žå´™õ\:©C·Wû[¶¹­“*ÍãB›A{Î#_>ÍVÝs&˜¦8ñÄžHÂý÷±%ßÛV–ÄòRkMIf¹®¼² _±†x屺F_ªÒŠbz5{Å%“Q(®6€ ï,øøc:yÛ§°}BO<Æé˜Åx?I4ŸRžÞa1Ç`Xl]VóÊ;œÞ†h4Úå‰'´Xà‰G1Þåx„bè¶¾¡¯ßÅ_ú×:çH9 ð†­}°˜a´ Ã;ÄQ™+ FÁÍL_›Dšª×ãæ–Â°ÖrTîJð{<XL|81 UH§ô(oqÖpeUÎ#Š9Ÿ—gϱÂåWÈ9VºŸ(j§0DÜ«U®¨FÛŽaˆ¯ß…ÑZÌpß= #Õ+žõÓóžÞQ„<¡‡¾Ñˆ76lPÒå¸èb‹(æÆ†«°,«d§4)çÙ‹9áÒËç­Í ¶ä]ˈ­ZfZhKù–-n!àÊ–0p¹–Ó AõÎF­nÙv/µTñØ’4iòGqHÅY`ÐÙµ/µ¸ÕºÊãõç&äÑ Ë`lãÄAÀeå)ía Þ±9¡TÅyŽ,EAޤ‚ÇápPiû³RΦ°†x£ elP²å 'OØÝÁà ™scK[û9`0Ôpƒ¡öÀ£Çô ?Ãÿýê6’ÔÉã¼ëN¬®òàaͧ˜Ï0(K1›Á†ˆcW Z ²\q¿Lýò HƒÓårc¥Ì%yyùŒÆ"î—¬lçéóbž B(“sÊ+Ë`-\ÎáP§·‘,0›é§ÐùR>±#~ƒFζЗt?ŽÑ.½‡ËE #EQC÷BžËå ":Ïùo»Ö”w «;‡Çdz®d3ŒP òŠqDš–}ŽÄÁ€Å|!€7Ü ù¼øNmæÞ’Ô„½©ª4RKÓ°ËòoϸZ;ÕZްģcgpVÞZF0‹ùž MÇjqŒÚ"Ll+LV­Eù­œçƆ€‹DQH ®ÞÇ®DY‚ KC µ ¢Ž“óŒ#Å1¶OP–ñÞ7¼ÎÑtª3ÛœM`Œæ Æ!¼°³ÃT¯~]YIç¹öÄx„ /ÂöI-RžÞÆbÁûîÅp's4ÒbÁGÆss³s<\ñ5+øý÷êGß…ù r'ï¹²Š ÄlŠ4ELÆ—R±–Þë—â(Æ+ÏJI ¹ãd¤MLÇ ,âœàE½JñÈìî°¸íY—SÒîH…¢Që8§='·eà}80w¸õËxÊ›°X ‹É7Kø?SqÒhž•¨ùb†~ŸÿF#®¬4‘Ó;†zê%ü™ k÷èsôúðŽYV‚ËE f3É3°áÛVläUZ—Qã+¬ÛîÖ!Q{ÎôkdD» ND' ˆK0h[Ô°ÿ 1xàè²賟âpXm’u„“µt¾U#ôQ5(ÎÑûB; iáUV¢‚HQîIÊ !l 4¥¥ÒŒyVnK>ë*ý‡?Âém¾ä&^r öÀîŽz=ÙÂWïÐ'?Î{îÆ›ÞBïåsKŸÎÉAÓ{8ï°µOOì×t‚§NbsKòU‡Ó>Ï“†ïù ý軸µEÊd¡dÁÞ†èŲ×WñÕÛyð0¦,æZ[§Ä3ˆb„âêö¤  Î&®”Xðd¢Þ€È´¶Áù=£0¤wH’2‡§)£HãXgN#Ë9\AšÀ9 ú膸Îa3Ü+MX‹;nÇ`€7¼Yg¶ Žª¼£¼C‘\Fo@UÞ¯O~‚++mž{ž^óz¬¯a6GÜc–è§ðä)Øë˜Í0Ÿ†qËOpN6À=_§:‚)ímè’Äʶ’oÓñ–šyjÙ8Û‡ž´’„ºÇ Ö?ÂzKKý@‹¬Nm´Ê÷ßW,¡¶+iXòe©¥‰[é&ŠðÕ;ô¼k9•ÏÉ’¹+Gî€,YOà dYIï8Ÿ•›_Óõ4‹™Ö–§Oã}¿ ï±¹‰¿ÇŸÀ§oV¡ßGÔÃ]wêªgSÂÆVáäÙ@^yÎA¬,+Çûr0Ä?úIÝüI~äCèêÛÜêé)ŠÞáÝÿßv#nüve9­ÕÎéB¶ˆ§OáW~ ý~¸ú½òÚ=ƒ}0Ù• ˬE4®Ø>ñ CÌgÜ>©}û9™Àe%9'Šä”A¯9䎆íb2"38#çò7QÔØÆúÖÖ¯Þ!½>ý)>¯¸R³ ²¼7eàäÌ2ÈËy’Ìs|à†-u9Ïá ~èG0Úå|!yÊxþ†úC8Ç äÚz!ýDcá½ Î/ û}?Ž}û‘eH2X³$(Ø’®êžS>µÉ͵²Ífh°Ö´IJ¶¼ºÓ6Z@ s·ìLÓÖ‹l:ø®=»1"h=p”§O£×G0îag[IZ ÷ˆý±»S®òT0q¯¸wåŒ3ÍKyÆ(F–(66ÈÅñAZ«õõjDOìœábŽM¬oâô6ââ~Iƒ3Fy†UÜcšpç4lPÎò£,ÅñãXYéÀ{U¥P ’bI½¯4Ÿ•üþïáúëùÂam YÆXÌ ñÅCÌg¸åËøë¡×kó f¹¾çmœLH#S²,åÊfSõú ,½ãp€ER‘¥0Ãd^øB½ò;˜LðÅ/à+·âرò#ØœªÑ=A®9‡¨¬Ž½g²€@kF´,™Ëʼ’dèºËR©ÎeɬfûŸ}xO ôÐ7`,ÔÌ?j>–9«d/Q«Ñ!¾ðy¼ø¥HS¤‰LÀ˜Ø=ƒÃG4°?ÀîNyÔF¶ɸ§b>U,é%sXK—£PEs”áAªSHP\Äñã8~‡ÎAá·4XÌ*€öÅY¦Á󈓱œ€'ø]oÁ×ï¤/“t‹+Õ¢Ø^p~äÇ0–¬›8FâGÞ‰4Ã/ÿ"?ø'ºòÊrñ ¢ý\NGyÏÁ@Éy®•Îçø£÷ë¾{™ç€ô¯þOþÜÿªímF1ú},™e Á¸G—kç4s‡0R`á<¢ÿî—5´ô‰=Av6A𙉫«ºãÞqÖõ7ðéÏ@¯8Ö½÷ð“ÿ 'O!MTZ‰MÀ9¼àz¬®¡µ•‡!DG0\á|Š^¿$Þ†ÎÁ9¬o wHM§t9Ò¬XÒ×s®áUWëƒÂûî«W¾J` ;å‰ð瞇ç¿ý&c|öÓzänmÕ¥MetÍùtõÞië¤ã–p}²AÝ%ÐðÁZ‡’.õò*MÏV,5Ûý£Ê-ç þÐëȹåp`õØëËBÅr4ó\.g#$q>À$Õx‡Eü°îúþüÏÐ=fx)ûk>Ç;þG\yU¡!/ƱŠÝÀr2Q€ó™ÆcúiVlšëâ·“+«APµFßý½¼êjüû¢u$œÓhÄ_ù7Èrüài0à¡#0”Ë‹|*ï9ŸÂô‹ÿ‚ãÖ×›FÒÆ¿û-ØØ‚<ö”Ë™åJtó)l ïéâ² }ƒüA—ܾt¦kg±s@ Z\ógó² è÷ElÝR¶B›ôš×ñ²§• ²yVªV‹õ CfN´! ñÄã:tsržóYy£ “³Â4úÕËÝ‚'Ò§Ò:¼lõ³ ×</z1çó2Ž÷ûJ¼ç7øè£ŠãåC¿›ê¤u§Z:Ú¾Íí{èA=Þq]qAÓÁtZ®jðµgw³9cGxùz㛑¦„”¥ì °¶¡~ŸÎ ä`yͧÌ]ASÁbÎż d–* ù‘á–/«uìOû˜ƒòqE1ò§±º‚ ,ÕûÌgð®@y9Â9¤‰?Fšr“8M°ÿ~êcu­{ž.j2ÆÞÄW½£±$šR…WÎÓj6@¯§¯ÞÎ<ÃáÃÅaåÊ2x¯rã„Ðñü_ÓÚZÉy)’ež!êáÜ#:ÿ«Í ^wƒF»LX‹ù´\[ñѿ—¾kZG”.s^ÐÌ«»Ó¸tBvsªE1ó¾îØÞÖ×ïB±ß«Å àÍoÁeOCšAqó ÂHY^œÅ¦­}$K=ËÊóxlÀñ.ƒW%.T®˜ÒKAÀ0Äÿö ôÑ=ž¹c¶ÎéûˆçœƒdQ¨Ê"‚p9œCÜÇ}÷àÞ^Ü=3¶}¬íDÖæØuĹð‘‡qßÝÀwŽp­v š~¼‘êÀqÍÍ%¡;¿Æ//û]~¯‘î¿GïÁCá¥7Ñ{壈¾@]€ñ^c2ÅQ÷˜Ïð…Ïʸµ@“j¡R¾§-d (càR¸§¸ÇÅœ.ƒ5˜MTtÞVVárI´Fã1®½Žw~•Ul®/˜[[úŽWj2eÐ;Ù cl!SÌ”gØMðôgh°ÂÝ3xüq#E¼‚éXÖò)bk‹iªöÆwÒ»ÿ—½7·í®Ë<ß÷·æ=žsçÜ$d „!@E ET‘-E»­R»-Dz´Û²•Vª°€0IÊ`‰"Sƒ„„Ìsî|Ï´Ç5ý~oÿñ[{ïµOÒOùôýWŸ‡‡'¹¹çÜ»÷^ë·¾Ãû~^<ôxk«}/ü^\}5âDaÈÉ„§Oáo>ÔÀ}÷™šZ6vÔ}!È‹áõÊ·µT#¨¬ØéàMoÆ%—b{ aÄÍMüÓ'ôwa6•EšèÈ1Ö5Ê\i—¶’sœÍ¤Læ%‡Þ€Muä<åuÙFÊѻޢFé0Ä ^¨¿û(ã„(#@¡(ñ=/ÂÑ£jRv ùŒ€œ¥µ0\ÍÇ\‚ïøN|òm¦×BÏÕ1¯Ö^°µ‡n ËÑR§‹»ïÀW¶z€N鑆­¥¡ñ‘½ëkgcÐíãŸ>Á~ô µ&õ™OñM?CG0Ú•užÏãyâ>xr>x‚7¼sÅ‘m§?,Ymþ%>mÁ5ê—) .PTVŒ"9|õ?› }¯Æ2_ni´ö<•66iãáØÈãe|´5ƒeŪDb>GÙX^pÉåíÐ|Î8V±ªÔO',жÈeÕ° †q@ïyz=!IͦÈsöûØ_™´ìŠí˜X>B=–—oÓ)¿çûpýõšLxþœ¯7tæ4Ÿò>áj¼ýÏuþã“)O<¤+Ç£poQÊ¢@–’l² Ëœ&Àö9…£ÓcA@aàü=Ù8P¹àd§ƒ²Äe—3Ž×E?Kæáñ qÝS9ŸËÔµ—½d·‹(†óOQ‡g>‹ŸüÄÚ‹]%S­ÛlË–ðnµ2N|í«þ0pß½LR´B`¹Š¤]Û@rµ•Ôzñ¹ÊåDc¸$E§‹^_YŠù¿úËïa6Içdz}zéhUj>§!ÞöVœxQŒVô|D³RèÎfœ.^AÀºÔh‡e…¬#Sp~ƒ–u”u`Œ÷UÁGV®á$)x˘GLYBºè1 Cú‘Y² Dâ4œMýz‡ŽÀÃzgSúù —ͬ¹1ZYqÍÛëyo´êq„Á ð¬P´­Iµôb+‹Ç𼨭@ IDATLíu?AΟç+^‰kŸ¨ñ¸yúˆ4u-¯~/¸ yøïîRÒxŒ ž±$Æ1|¶C]É9Ʊ:]E±j [{@úåçó%©.¼ÈcºÕ*NÚÛV$W…ëž k‘u(¨.á„N‡ÝŽ<’SãVýù_äÎŽÖ>¼5yé’×´„-Òb´ ¹‘—©Ÿ=Ó’Bœ;íÙ2­È6iú†U •VBT®+µ[DâU¸°Q·ƒßøUmm!Ÿ!I¥* „Æ7¾¬*ýö¯óÌiÓ(U:]u»ìte г Ù ÖbžëÌi£ªD§«yŽ4C·« `ÚQ¯¯ƒl íª®X×, E! ‘ĘÍÖøUÍ+tÌ:taȲÂpÈ{ï‚1ˆôzpUåŸW˜MUUŠ"@tÝ.ÏAÖA‘‹ôžLìíú[½uέ>†un€)[3nq ¤â:é\Ì.eËÈ6ñW¢³¸îixìM+ï7’Ö‚T5ʶ2Ç ¾»y€ßyÒ”ùUÅñ!Ì&ô@RÖÁ§Ò ÈájÚZIŠ´³¢FA>“1NŸÂÜ‹ÃxÌkË™ÏqÕ¼ÈiBJ%ió„w5LÀ PÃZôzzõk.?'kí…`gu ·WÑíåÉâ \ì©B¨­ö¥`¬ûð÷OX×Cc¸¶™c+ibéû! Çÿëqü"\|Ã×\‹Ý]~îFÔ•Nœ`! P[]xÏz6/¼ˆQߪfœ¢ßE^âÜYÜy;>w#ßý.>Œ#Çà¡7u‰^y4ô‡ªDðè…ªJäSÎçˆÌæøÚÍÚÜ\ë÷F|Ãuðóáæ3N§¨kN'Ø<ˆùTCPu $érâíl@Qª×ƒuÞž«S'餲dagAÀþ@A V^k ¥¥àeµ¿lR¨ÚBGq}¢±Öе^ [ ‰|ü•(æH;œÏä,€r (±,F8rÃ!F{¸û.|ü¿ãù/ÔxÄ(Q`š¢ÜC\æ3YKÏýüð‡ð’—â1—bk I‚ùÌË€îFcè¤(bb2V>k«jdžã¢‹µ»ËªTœ0J‹vÔDªªpðΜÈÇ]‰ýq̦ˆBÞt“î¹GÓ)±Ÿ+ÆÑ²ÏX/æ›kÛxø¡Ö 0¬vf-Ëf‹¦õˆÙ}À³¥õ=ëªoŒÎÑÙÓôÉO"4Œbø'¬ç·]z©^ózž;‹ D’ÊV|âÓ…,æ˜Lżð"<ýz]u5?ð>Üð.ýÔÿĽô†È:ØÙU'c`XY3åíÐ`Å»ïÖ|º@Ï·xP«Äê–ž±¥p\I—¸öös%Åu5çâ;†´KIY‡A¨º¢­å ³«JÇ/Ä©“ìtÐëaoÝ.nü¬$~× TWÍí§¬Jq0€“æ3þÁHbUëþûÐ00ª-ésÓ\st°´y®8^H@¦Ö•Ò”a$  cBzg3ˆ'ÆpCUÅ8ÑÑ£¬kTž÷|šï~‡|€Æ¨ qh›Vƒ¾æM£·}­uœ<¥„»•¾2Õ·?%Kˆæ[ГֲjÖÇS sÓdd-/¼¯~¶¶Ðí®æ‘ P—ÜÛ‘7æÍg0óº§b>Ã?€ßù-<ó[ðÌ…NýG£“ÅŒ#Êç̧ºà"ìžç=wáþƒä–»]v¹÷p4𕳧9Üôrߦ‚KÌgÊçp–Þé‚ÀO»QÕ˜m1IAŸýAD ¦“æŠyÙ+°·‹éƒ¡¾ÿE¼÷n}ì£xð†á£(ä×\kêö–Úe-±¶­X—C.>p0µ‚ØéÂÚJ$ãe~Ÿ'O 0 |W‚ÏúÝ< ß¤àX+ZUò#“ DY0<â04lÄ—¶Îá©Oãu×íËY’´J°,'I.J2£–¡š”Öº_r;¾ô4/²qà¸ÅzkÙ´ûG-¯4Û1þ ÛØÀ¡#C¦lD¯‡4ÕdÒdÆx·¸³ÈsnGšéäÃøÑçÞ{uºÜÙöó9Eo›iOo [£,°»­é„ktk§"GÖ•Iu» cä9òÛçxæ>ùx×_bwq‚8Æ|îÓý܆ª+vº^ÊÏ­ó A ˜ç€F8z³.Ê;[( ä$üð0ÍšÌ-‡wÔzKК0ìW ¯g¢øL§edªÖDÄeÉî“'PœY×~GL¦žd¡Ù\>kyÕÕÚÈ  ÂU…éÓ ç¹ŒQÖÅx$¿ºyîwâë·âk_S¢®Qä$qôtz Cu:0wF`2«^Ͳ\±§¬¬0Šp×rV«QìO@G°®9J‹\Q¤²BU7`‹ºV]#`B¿}ÇSŸ†ªjÅò«@qq „«€þ¢Y&z-ºê¦XRÝ×ë¸ÞT/„FË™ßÓ²ÒgHMv ñIzèÈñã8p½>äƈ<¤¬Ó<1| „'/D1 †xúõxíë™fH3HŒ"ZKIÖ†íp2ÆîƒG­þÜé—\—ÿk=ë_!Œ•f”èê¦å õº¼ù«øìgüÍãWž^×íÅú(K& LÈ8¦„2Wš*ŒäùYAØ ñ’AàÓnT—¨+<ü ~ê§›,ó%Ê™ÄlÎù\‹!Õb³´¼c÷y§V½Ú¹í\CçÈÜ}L@¨¶p¶ù4¢nÀ;‡^þ¯ñý/Ñ‹¿Ÿ&B’ ×'Côû>~Îb>c‘ÃÖêZßð Ã÷½ý°œc€á&£¢ÖJeéHÎáÚ'éÊ«–Ááj|ýþÖ[}¾“ª“1£ØWÿ,ærÖ"N†¨KÏ™m„€®–§ÄJ8~W^¥Êjç2=ê€R³LÎ-žQ´ÚØ· AjÍÙ¸zÛ7p;qqÝkyq™Î$YË4åÁC8rDã–þûëJ_Œ_ù ¦ÂÁù\u…ɳÒLý¢˜y¹æÉc ×Ã+^©£Çfƒæ%zøÜ™S:wgO¡ÈUäÍË>ñpCÅ ßüoù“oƵOæá£ìt„p>¡5eo ?Œ;ïÀ¹³úÊW4ƒd’4–4U¥$AÚ]Œ>#õÌ2FãDÆ(É`ŠBÎCÉ8FÖEÖEÑI×=}‘å"9Ǫäü~ðeü‘cQ.?«%A-{¸Z¡‹ïB½°¥­æ§_ýgÜr³¨æÇÖ76¹qÝ¢Ö¡®8è±ÃE— Ó¡?_ 1ÓWY‡IŸmzñ%Š"¤ .ºHI›¾ÌßúuÜþuÈ 9§¼@Y²,Uæ>(UÉç=ß æ[­äâ®C|ðýÚØltGeñˆA€ºRYR–Ñ9T•ü NËØC[Á„2DUãâÇÐÖ 9s+"rå â˜= D]c:n7´Kž" VŠÚâ6XÅ=/Y0Üï€pN$žü>íz<öq°² BÜ}7>þ1Þ~›z}@ õš×ãüYD‚qŒ jºÌ$߇7uâZÛ˜ÑêYÆ8Áö6âÂHqâcù”¤ TÙ„BöR£0àÏü¬nþ*‡zÎw ,5žbÊìweÎÆ˜çêv1ãƒÿ­1‚½çzíOÈ”Ãý!$$1M 8ƒÙ ù¼qømè<§µHÍg,+8'€ãh8d>W§ËC¨®qùå¼þõ”ë8ȉU‰_ûMÝ{/¿òe}þFöúk  +ÈǺÔq=ê‹+5âÝïâ¼×\Ë|®(Ä`“Æ@¶i%çSxµ€À(9Ü„­›àñ0¤“æsÊ!Í”¥cQšìq>ÈÛnÕdLRÎñ Ÿc¯#‡Yˆbͦ CYǪôVZ†!:}F¡LàY°"™uXÍGN ×Wœà‹è,ó9hpóÍ'}óRÅiVÀ™Ó S¬*UŒBÅ)I9l8EYp:щêtÈ„œLýíóç=CAМàSž»]loqÅaXù€W&±nWõ>¾û ¾wo¯üQØÀwÐçˆ.+íã  l“õ(a÷ûÛÎE|¤#6½éÚ·µ–Z¬å±r1s]{»Ê ^n"G{ø±WãÈa JVU#´¶VÖ6Ñwý!^üƒ|à †˜ÍaŒA]b”øø#!ëÚÏÂ@èÐQŽvÑíɳ=Æã&/~0äÎ66¡,‘¤M5Y×§ºÈájË(Bša6]¢Ò`ˆÞ€u¥2Gšr´§ªÄ¥—ÑÚÆ¢@`0ÐÉíxÀ??ž’’Œ"yž Øë£È%‡É„¨®„HÑ0ë²,PW¸øüä›5™ éÀMýÃE QD+ôúœÍðüâmo… qåUü¾+ŽY–<øT<ízÜw¯F{¼ü Ëñ6Οǃàýïåp¨•^Tª,Ÿþt>þñ*kÆ övÙ€=\S1óâ”®F’"ë ,T¡µ* ÙC1Wã*‡ÄA_úžù,>ü Ây®(& C0 lözß½hiúÙÔ/´ÑriŠ4m®Â,Óí·ãÚ'64´(fY´Öã‚PÓȺx÷;Ñïq}è¿O÷Þöp´À,Ø+9•ZÜ9¶†?¬‹Zóä -ˆtÃŒ¾èb^v9ËRIJkÅŠ‘—‰€D#K„øå¯¼Â ü¼Be ³™Š& µètT[ È:šî1í°È‘uxääÆ&âu­½]¤%Um [kw £I †J‘J3ÉÉ»XHÏ$•„8¦uô´Ox<“«±XiªÏݨ~Ÿê¡û‘$ @Œvº #”¨JÔ•‚YÆ4 ½Çª¶HS9IA€Á›Y•´a¤á~ës•¦,K9ò\EnG×^‹ßþZ1×~м '¡,üÁ©Á³C[Ç"WU„Êçʺ¹‚®¢³¨J”U£›×;˜.0"a¤/}¶†—9&)l ‚UMg%'C|Ᶎë\¸•VfHÛ"‘<ñ0ƹZÎ6¥7Ý—‚þ|?uB“©_gµ'ïm²yk1âÜ9u­ù|E`Û¤'~Uµ7Y+ A‘óÀ]ñ8^y¿é[õú>Û”r´5œå2r0‰%ìtŒ0d]sž3 F…°ŽûìY¢ÖúÊ’Q¬¼Ð¥—roO+íßÂS§8ŸéÔI:§ÙŒM›ùŸùTçÏIhl1£:]d) ‘fˆ#Ö5å`-ýðÛEÁZF Ç’9†¡FY ¬xý7è¿ÝR¯$E”psSÉi‚A cü$‘&À<ÇË_ÕÒIª+<û9¨*€ðo³ÜqKíE³Ñ êŠIÂùTUI¿~©êf¹æCÜþäyøpƒØèÄ|ίÜä¹”ð2uOT§sùùÏ7Iž+KϳJj9þZ,7•…þê}ìöX˜ÏE ¢¨qÛ‘rR·‹}„I,×d?/d¾\aÁVÃ…µòì?ª8¬N÷VÆŒV Pí=ýÂÐÚT"ðc¯ÒÁƒtNIƬþMÆÍŽ]EÚJqŒ(fYÊZÆ S¿Ïù UEE}É+õJ£$ÆûßËü8®¹†?ƒ!|d´ á„$ôBz…­!ëa¤ªäÞ®œcmÑé"Œ$ëk_Å1ëºyi&P>GøˆvLG( ¾ä'üàtÇíêtIé¡ùÎÿÊ×¾§Ï4½ PWZÐ’yÁpU ?€µ¨mÃóx÷ùœý¾Æ#!ƒQ¢N‡ó¹â”UAYBuÍÚ àî6^ðÝúììâ{_„í•2;‰Y×xï í5ðÖGóyå ×ã)gnj{ ¿öüìÿŠ"' ÂÈ4²— /Äÿþ»8ñðbv²æ›æ:Ÿteçáh@ˆªÒt‚$]®_?ø-Ë‚•šCÖ"‰ðã¯iYI‚nYÞ=TWMôƒ <4ŽÖ¡È‘ÏF'Í«ò«o”V΀'ÌyháE—ð¦/ãÅ/Á3¾ Ê¢‘(Z‹0¢ŸÓÈÄ1k‹ºR֥ЂžÌålØÚí4£"gœÀ yg»=9±ÌaÈáÀ!Œ÷ôo^Å»îÒ_þ9‚qŒ¯ßªÿü6<ïÌs=ª¢¤³œN,`;IB9T¥œc§‹ƒ‡1ÚS¯Ë½]Ô»=äszºh£“q2A>gYxm­[`v ­E NA@9vz‚àÑ‹ .rŽ4C]s\+M)!ë0ŸÃY]x177yúÌŠ"+0N0`óL¨ª†Y¬c°·ãoY‘gO#I0!Œ†0†Ó‰nþ*þæƒêÓΦkJ…,Ó—¾À»ïÄw~Ò Y†é”÷܃O~BIâƒjV× —Ë­SìKg\Œ2}ÿk¿¢W¼è÷=^ U¥Ù”ÿé÷ ޽±¶%lRŸãÊEôÅr†_”BÔ–yŽÆÃõ?yýa´øë©U³“áU¯E·ª”3ª+ÊÉÖˆƉʜ•ó˜X8‹ T>gÖñ*HÍ&žðJcD¨+y|—¤(¢1J38ÇÝm}ï‹xÅã4™ðè ÒÌ>X×* Ÿ\ϪjœÁIʽ8¬Ó'èÍÓ‰Ž]È­³·Ã˜¦ˆSÔ¢aÄùQŒÄàôI?ŸÆt†K/哞Œ¯ß*C¼óÜŸ66ð²Wàq‡ßïÌf2æ3!‚I ó¹Â»»‚üíªº¦«R¶æ|&WÓ„Jˆª‚Gc”%²ÆcÑ0N0©S]Â98!Ž$Á‰Q¤²`·‡ù”eݨ366Qä,K\öX=ô·b! xã§ñï ·ÎÁY†Fµm¢°¢É£Qƒ¤‚€y®¿ü‹F™C#k9Ÿa0d+R’knL!Š4™àï@š¢ßÇ™3Hb?)ZA¹ v\þ®hÓlq÷g.Ç1þâ¿ðØèt‘ÄœN1›ao„ÐÀ¸…ÒŽ-]Â# B-RP#Vó+úz‘+µ´§¶´PÚ¡,À9|Û·+ÍTWÍòטF’φ̺ètûŠ¿Û¨ÜÒ„Q ÈZÔ5MÀÙŒAè1AðAêa„8n¦cå7ñš'â¡ÃpV¶9,}:/!Íg˜O¦ÍÍ9Úƒ18w–;;Ýöuþ¿Sb뢤L [£ÈV{>Ç<×pSã‘h䬺=u­x)¶ÎÃÇH„¡œåö?ñÐï+ŠeM¥­qî4&#J²5Š9‹BqB…!¬e]+0ˆäsd&™ú=úõŸƒel/4šM…œŽ›+¾ëÔµGÑçô†r¶qÛíì`o9öè“Ñv{xþ }'¸J²Mê‰1¾ÏA’±Ûk‚‚’Ó)§Õ5ëUA¾^ú}ù± ‰.•2$™e$9ž Û…OpB‹&¸´L¶­'´ui”çZúõ²8ét4ÚÃéSxà~œ?¯ÙL^8ÔØ¸öÂögipÙøß 9´Zf µJ¦vÌ0ÛK—…ð'ëð1—64ç䇆¾,žMÙé¢ÛƒsH3„±$t2OÔµ,æÌº¸ÿnôúèå™éi”Š‚QØØLë¶f¡!M=Zµ¥,êqu­²D]û|lU‘3ìv›MÖùs¼áä­(æ;þßó"MFuXª+:+„þÀ³§0@¯¯ºVÖátLèêkyò„Œñ©˜ºæΧ€4a>ó€”9вÁ¯ž; cu4r:ñO*š¦ å,÷vT× ôw°¡É˜e gQW¨*†ðÒºn´i§‘±:1Ž”&í©Ûc#ŽpþŒïG!! ŒáÎÓDæ<ã™(KŽ÷Ðïˇ¦Å1«R>>Õ¾ƒá&·Ï!0êOßFpM£JƒéŒÇã ×ÈV´‚¡î¸ƒ[ç'í<9á£U~¯ô(çeïÚŽ• Ÿý#ƒ!ÑNF‹>°R©ER_ö· št¹L›\Kbß³¢{Ø7X]ý™iªÁÀ+ûÅtQˆ8Eœxº¥êš`È0jçS„8Ÿ*¹XôÂLv%ž'WªÈF*rƒáÆâ10 e-g“fŠâßÒÉXr¾Ó¥s a¢ªèø‚wã®;ñ~“O¿ßúT§Ç¢ÔÙÓ8tµEQ ®¼h¯±tʼnÆ#_s `@ÒÿüïÇ^" »·Ó¼ù†"'H”¥îº“ù\ßõîîÂZI³)çsx†EœªÓ¥„ÁPã=NÆxì8Þþ§xƷફç0¦Že‚,K$ w÷…´µêŠ&TÓÖJ: òZ[[Ü:ßhºÆ>ïù:NÖ¡vœÏÔéb6mX¬£L(‰›QäzûŸñÔ©†à´ì#w·ñâ—áI×À:$©Âˆ³ Ÿý}ásøÀûpè0WI{í f©ã"l¡Ù^áÂÁ5_¹°ºC¸N)i&«PÔ–ÿ}ñ,XE´½˜\‰v0 ªBØæXÍz¸FÔþ ±Ö/ë ÛÅl.°±I˜‘'ͺ^ô¦Fß8›!ŠPCG¬J±9É0Þ“D'Úr0!Š&€³ Ô–I„ Pa4F·‹Þf8!K‘—"&ð4?ïÔY•°uö½|Q¤/~ÿôÍ\iÊßù=ŽÃh$’EîGàÜÙjÞbgÎÏÿËÃMY‹ñƒ!Ò Ç£Ó'šMª àûý[:ÅÏ|Z/=×ßwØ~pi"Ìf¾À¥_Gîhˆßþ39…kž„ºÆ`C½w¶UטNa­àèCäsÕ5;^K̪ƒ€÷Ü¥ùaQàß ëe$°u‡²•". IDATÈE U“ƒ!‹BUÅ8m¨¦Ÿ»‘·| Q¤UX„`_ô\÷d¥–¦A’¡,øôëuè0ßýލ±ŒNYkgµ–Û¾ê'Ùb®‚³µ|$H¨*ƒ0Ðúµ¾Šñk¹ˆZÄ-¬Ç(­=J Ÿ³®Cœ:ᡦ·mˆoåe`Íwé¤ó^ Óí ’­A²,B”%¢Öo‚Š Q/™ÚÝQY M±yH;[È2å9ªƒ‚E­rÊN¯ÙË©*µu–ýó†Ìçª-“a¬Ù˜IÊ @mQ•%°5æ38‡[o…­Ô˜¹ÔÜ aÌaÜ|0MŠ:!agQŒ|.gÙßP·+k!‡þãÊB/}¹¯F4ÞCRÀx„^q‚n×?y0¢,âþÓ {]?Ë?ø?Ðéò/PÁ:v2ÓÄýF‘ê £'c¼ã/QÌ„èõpó?ó߬é“1|—E" j>ƒ7ìF@OÅó4llàä üÝÇ` EÌfø†g¨È Î>ù0z=õt–&Ð|N_@z[„/~¾Ò-}­"û}<ýzT•²Œó9œC1Õ%LŠÇ>V‡`okWÒú= ÅͶv-x«„÷}õÞ—\Ê'?çÎêæ¯ú½et\™p[;e­%ÞsßH´e¨+KØÚ`k ƬJž–Åk™§³†XµDYÒû>_Ô´A4þ¡ _Ϊ*乿SäƒP~^™ÏTä¬+9qw‡AÀñˆ¡³* L'¨+Â4k—4HW{º–övQ[å9 äé‹ÁG¢ÓÁ`ƒ¶B>Gš²*‘fºãv˜Õ³ Òóùa@U⺧*N1ÜD§£0D·‡nIìï+†‘&c~ßK†¸òJä¹fS 6èÅvã]Õ%Æ{ì QäšMqÁ1Ü~;Þò‹ÊçŒürÊ̦zà=F‡Ž4jÙ PUs2ñø*@MNŒ€­ó8}ŠÎ®t‰Î­É“I£}ªJnŸ—/V:~ú“zë*0~œ-ˆ¶f]ùYâHÖbw‡'ÆÞ®âÈÛÔëj>㙓˜NðÌgù¤©¿ÍêâÇ I' Be¢®QW "_ìñé×£®Ùr,´Þiµô«hy®tôh gY‘a„7þ_÷z|ã3ð¼çó-¿ŠáÆ¢ÓU[¥¶ôÓi=<Ä»)VÒ}-³÷Ø(ÃBínØeâβmhOŽ´žîº@’:L'xøa]x‹¢aÿ7iÈ Çp޾&žŒFšŽuu$‘Fókjn §OêèLR…!;]9G딤œN‡²Tpg¿÷;øý?âx*Óg£õ'Ò„µ• (!ŒEÊ v»zûŸs6E’¬ié[ÀJˆ¼ìåí©Ûg°*ÕëÓçTçsCk¹½…ãâ9ÏeY"Í<öTe ”½Kk9&]´µ\dÇ.RçµJ¡oÑW &å9^ùãØÜÄl†¬£¢`^àMoÖŸý<ü M 6`YM-ë”ÕCfÃ:VÀ‡¶NÆ0†KçQ‹¸·h_ÔÖÅùû¹Õ5nû:³¬Ñ!@…!lÅá†êºÉÓtN&P¿O³)ªŠ4èt¢E‰÷¼›ïø ll2ŒaŠèv™¦ 9¡ª„ˆc£÷Þ 8f4vu9€JÚùLq'ŽvðWïǽ÷ IÖˆy­¢ ¦½æ5ØÚ†1¬*D†qc§JZ‹Ýp—\Š4ÓpyÎù „É„A€8fžëë_ÃC2 ˜u@¬ÅØÁ‰ÇclŸ§$‰ý!73Œ@ ÛWœðÒKøøÇ/ÛC¤ÞöVf™ê& 7Ä%™|½×í"0èõùá¿á?~œÿw¸õÈzo.–Íd¯‡ÿ=—aP~vÙí"Ídì ™u¼(ƒ&À`C0ˬ ÿÌ ªpà ¹EÑp¼M€ Dš¡ª8£Qû,NYÿ.[«é[[ØÚÆÖyŽÇ ìWÛ®»´›øˆ)ËË.Ó%—ÐD1ªŠa„Àpwßþ܆!ÒJ®SÛýÕ œ×ZìÇJ¿ßÚÀ¨(Rþ•C͸jÙØ<ZwTâï>‚Ó§r²4l¼)0>€¶ –¹s~ïéb°³)œCUJÂl‚ñ¯yƒj‹nµåAçÜ8€Á\¨Nw݉$ÁŸÆM_ö²A¿ÿj’ª‚µ4wÞ®?ýÏøì§>µ¶gœjç.§?ñ ¥©¼…àÜYøø[[³®(Žqà !èà!ŒÇ˜ÍáW›aÌ´£A½>:]=ç¹xñK䜴?Òey¶a2ÆûßgÇCÀªj'cL§ú‰7ê’ËÊZ©?ÐÏþ w÷` CÄ ƒ€¤ÂA é”ï|;nûºeOkŒ¸ˆÕ@ñÖ¯©®š[(ÉÐ(Nü©×œ˜&D·§0ÔÖ9ŽwuÓ—W6ïePäÚ:‰Ó©'¹ˆ ÇþÍnxu17—xãŸÁŸ|~÷÷ñÛÿÿáwñ†7⪫åI[ ÷ÕÂï¶Èõü²ªàYÙU@4HSôzHÒõIÓ ªÁ%²dÅÇR{µ»FP²’³‹ù>Éuêâja¶„hY½5H„þ@_üƒ ÙsYÇ2oêÞ@XÎ}t;Ã@~É€.lÅnAÀ0bÖÁ­·èµo@³,4ª˜!Ÿ«,šÈá|ŽªäÆ<øÆ Þ&cÌç¢ šÝ"GU¢*uò/8®g}+ëšÓéòr÷ÖäEØ ! õ¥/"‰yö4òœA€(’O­ó®§éY*9ž:©ÿö~þÉ[uçÊ2b{¦öÈÐ`{_þ"¦#˜âˆÎyŸšœü. fS:„ÿó?ñð¡¥ ¦YŒF‘n¾™”5„¿ÂXa¤°qó®;=^²™ó8Ç(Ò߬o{ŽŽUY¡ªP8z^òƒxýQU+Óɪ‘õ7¤aU#Má,¢r¨ê¦5ö»¢¿ØÆµþÎK«è ”´ra6/«.á\Øf÷¨«¤U™LîKÏ^5Ú`ò¾{‘ÏQä` ÀFeE[+ ik8ù´¢æÕµ†)†L:8«[oáùsü®j6cÖaĆkÇ(rL¿þÔ ¿_ý ¢˜³Þ#GPÖ¨+ln`w„‡Ô2øüïAU ¬ð¢ïÓ÷ã†wb6[fªhbKIñ–_ÖOý4âÈ“=±½Í#ÇTÌiu:¸qA€sgQäØ:§‡˜fMÌk’b´ÇºÚñÐa †ï-æ 00Iø†7á ×h VÆ`oUIŸ‹HÃ("€ùu…Á_ø<ßöVýü/aó9†›*sΦ* Ú³Ò”GÁIÓgOéw ³s ûöPH;ðNC¯ís–y…ªT·8âx„§>M'â—¾ˆ ÐÁCŒ"$)ú9ù†U‰bެ[#I0Ÿb6ᓯÓí·ñŽÛ›ƒ6ЧŒE1ãÞ²EÚ<Äã3íi€4C” ËX×ê Ñü| Ðë6ñôU¥bβÒ—4ÙMÆÐP4ñÄ'µ˜›ÚÚÀýlÇ—+~«}哵u¾)Э“§mÈɉ%ïÔNòF‹ÚÉYXËÚÊÖ¨k:«ªjRyªZU‰ªâÝ÷â)×éð1”y³1ìQULbþÍ_ãóŸÀ tUilõÈH¼ÿ=øÔ'ð²W "qï ~àSºï^!v¶tée8xU©N‡3Ï„~’Ö4«Î10°³%=ûÙºñÓ\Õô«–ù ï}7þÍ«T&™OßàÙ³xÏ >Õo5ùˆÕ×Uë(â– §(à,õsoÆg?éQàXÛ®‰+â©~µÌ^BU‰´ƒŸøIı:]˜€¶FQ(Ë8ùüS2Jd-ÓD÷ÜÍ_{‹F¿OIÃñßãìi †H3`q‚ù\²”Ðé6T³<ç÷á=ïÄ/üŠò9º=nPÒ’HÙºáð7]GØàŸ²Œ7Õ«åš®q1Z ¥&‰66_XK–qÜx;ü>ð?üªªæ`j~³HÐÿ·_r‹÷…Õ9ødš©ï4ó / òù™þ¬£Ïf®­Ž_ØÌ4¬¡é„gÎ*`-á È9:ç)2`¨¢„³´u…­ó˜N•Ïé¬úP×ç~§ )‡|Ž4“ýž~2j´h.3I¢µèdú“?ÆÖy¶c—%M‘ãèQ}˳xà¦x˜û¨l¹%bT«öw· Ä+CL/u¹áCÔ›^¯ÞäQ¸ªZ¹ ”iiŽÔ ´&e­ìÂ~W_‹¢ÀöynoãØú¾ïg'X W#ŠuÃ;ð•›àÑ‚YÆN—\ªW¿Ý>òÝ¢ˆ›š‹ÆW“Þžkm“´^˜Œqà`ãÅñ̬ÿÿëÿ»/¡®›‰ÉDUÙ˜à\í qšÍ1cw»ÛÜÞÒÎ6¶ÏsgÓɪ1¼ABh3××ÐÛ­œßµ°Aíáý 1›r-h²Å[‚àÔÄùz) ˜dŠ#‘z]ô:zQ‚ËËͰ¶i¤ÃˆIÂ4S–)ŠÙÉ'ì°? ÷ôUW¨j”…›`2Òx쥔šÏYä( ¹K²®UV°½8yyáÖ®FméjUu“ïé,¤&¹žhª k×\¾jþ_t‹KYm5<–k{B«-ý2£…?ã>\ê£ß«K¯iáU×}"ÍV•-œëòw™åì¯y$zn¨ÿø|4“?YÓ8hhŒŒñb ³P+…ÃPQ€ B0XÜE&TÐx6äórâqBoÎNSv2¤u{ fˆb&1¢X~ø±ïëØq`_ÐAk,Yälv>Ç|¦¼Àr` )yÛ-ˆbV%>ò׈#Ñø>MUMÿ˜òZ:ÿ!V•êÒ{ Pþ¿Ò}ïs}Še[eC¤ÏˆÄƦ†C;ÎÃGÐé4Ôß0∇b0„sˆãÑ Èqþœöv9a´‹Ñã‘ÆcÌfÌç𒸺‚µªüÄÏ4ü…ëÔÄôºÆèÿ ù‘œo+pàæé¬@†Q¬8fš‰¤«UÖ,sŒG²ŽQìQž«Øm“íT·?”k¥N!™?¹À¼žØùˆÇU;LzÜC«¸%.ò«¥Ð¢`œøH.±´RY®Ìé" œUY°¬‡èo¢×ó¼7YË(F·§4£­‘Ï5a2ñwHã¶1 ›PG^P\,œÿ•0d! ›ÿÅ1âDY†N‡½>úônh0àp¨á&Ãѵä]̦Í–$xëï+Š`ȲTQp´‡ù\|[ãè1Üz3?ÿYÜð!ºç=‹².C Ø<„#Gqì 7tä(76å¹òQ¬,ƒu„Cœ4mÙòŠ÷5zU¡,t÷Ø:½=ŒGœN0Ÿ¡,›Þ«ÈQ( V•?³Q–þ¿ªªPV¬+ŸŒÙ,—8þ #ýã^ÞÖüŠé§rKVòŠŠ!'"M™e¾Ag§£4Cš‘DUx ÊJu-ž:²D‹f=jP•Æ-lÒZº½ñˆªQÜ_Â#Mz´4õGb¶¹¶Ööt×Üá ¶±ßàbåjbƒ@ C=Æ#G‘¦èö0ÜD–5M¶³¨­ü~=ŠPÕºóv"â¸ÒÇ1ãq¢$f)™$H3ôz Ôb°Áƒ‡pô($øÓ,Þ(˜þúúÌ'Q•8rLEÎÙ W_KýÚ/áÒËq䨎e¯ƒ‡Ðé" WÏÖ²Pžc6ãxU²„­•¤ì†˜Œµ³ÍS'pî,f3œ?‹ïÇdÚldË’uÝà…[…Úû²•€—Izˆäb½ðŒrm”µ¯ÌÛ_Eh ¡é§ûaÈná²+pøÊ£=Í& ×›Ôéz/ ëZ÷݃¯ß¨_¦_zÒÿ5Obšâ¾{çÍE.é«l±ÁЮõÉõßý¥Ð𽆽tq·^¸UV’ú –hÿñûÓÎÑŽrpÒxÌ,ÓµOæã¯D€4EQàÌiœ=­ímVUÓú¢10ˆB˜“ &cøPä¶Ü?Ÿ£,qñ%xÒuè÷±µ…ÛnŹ3ÞðÝ–£-ÊÈÆ¾Xù¢tÕG-ß|c„ƒ†SňbÄ1ÂHqŒ^þ2{ÅÿMÚ{FÙUžé‚ϳÉ•£J¥œ%„„PD"çdº7ÆÆÆÆït÷ê{ûÎÌõžžÕ¾m·»qƒØ`ŒlrF`‘“„QΡrÕ©“÷ÞïüØéÛûس¦‹*UªsÎÞß÷~oxÂ]ÐMôžF}::HyöfPµP* ©Í-~vmAÓè9äNø½÷âÒ®OD!þ>@ßiVªÈ ¡§©X–«^-• OŸ„mI©ÌÃP®Â¶Ü#ÏS, þ‹'½Bj‰.è”Aí˜ë{¬"—ª©®ãx*¶sçcê4ôö¢÷F†Q­¢TDÙ?vÜ  iâ!C—qã9~‚˜&†¸m+ú=tW!Ïö,8íس ûö¸J-ŠK!ÿØ ¾6¯‹†»±úM ’Kshu˜÷J8|í rÍ;S–­dk+,[Žâ¡ýÒßÏBQò9òpö·Íï]  bTÏ#×ö|ælœ1–##C¨Zl¨‡ŸlÀÐ ÂKÜ€7bããùE]$€‡lcØ[›• Ú; é(—]ཷä “¦ÀdëÐÚŠúF`ó§¼ø2d2¨kÀ´ihjA×xe`é4Ê%œ8Žc‡ÑÓ#ƒƒèïáh¹œ”Kž•¹e!—)ŽM8"ŽMÛj€#(­ œMb¼bA,оbètÆnFKcÙlÄ¢ÊwÜQQSÎ8S&LF_/NäÐzNK.ç6æƒÆ¿xž7Ç¡ã@Ó$•f&#ã»9ïL ²q=Ž„™ägÊœ3Áþ½8°OJ%OR3ÆUŒJ‰9Ê s¡ ìk |$d3Q44k³¡*IID¶OõbCKpT+’ÎòÂÕX¶Bl‡›?‘Û1БaT+ž\¶ks¤XéHDþÁŸ79ŽØÛ:°|%:ÆáÄQ="GÀe„/^†æ&<ù[d²âFý#à[ŸSmÎCÕŒðeÆèw°êhTâ‹ãøÆ9^“ȋȦ)ÉëêH[;ÿû?øx=†‡åóÜ·§OÀò)¶q÷SQŒÇ!¸t]8ßc•QœklœawJÀ¢Â &!Ã3´?ÄürŽMç¬YXt6ùéFœ>…þ>ºPcÂtuo êÐ4Ö¤M´ªÄèˆ rþBΙ‡qãeÂD©«ã±c²úû<í‰*Ø„³*Úýâi½„#ÃPc>ðW½Ó©*£1j½æ&>"îü$ny¨|¥AñU‘C1dwÆZ*¡¹·Ý…ù ðñ¬OŽsM]aè4³¾-.)!žpBAØààªZÐu.]K®Äð¬{G¢R¡+¬Ò׃¾>œ¹–MEΣ÷:ƒŠcˆD>F>\O¤˨ª"¨é>œY§ÊÄ´,Z9äGàÞÏqê„!÷ý€ŽÍÑQ¯ ¦lP„:*Z#t¤¯'ç=»&QŒ¾¬&@Œªxù¿°/q“‹låÚ겘¿“¦âäIlÛ‚cG‘J"‘€e!e¢¾é44 …QôöB'4#YÜÙË<|¥n¸ãÆsïÙ¶ЕŽówŽÚrfh`­ÀN=yÀÚ·"_Ø µ¥˜ü(:7±4 ”,C†ADYG`ÛhkÇ _áÙ‹ñþ»Xû"{O‰¦»~xÊkÐÆ¸ö‘‚_`ÛhjÆê˰d9öïÅÚ—ppRimcÛlj‘®q¤¡u+¬àÊùe?»•¬˜l¹2@àˈLÖÀ±£hi¡G•,BÔX° ©f2*Û’ªá‹’ÇÞW BQODe—‡“!…íÁ}KLD2T °«hjÁ’åhmÅÆõrø0m ™ŒXU¶· s<³Ig‘LR×E7X.aÃû’ÏSÓDññÞwµ"©¤L›ÁŽ.X–ìÜÆ=»EÄ… HÔÖ1&Tà÷Xè…ÛÀwÇkP1à{žŒæòŒáÛ#©U,WBFpF òw¼Ãßž–Ã˯Â%Wð•çñÒsA"Z¼y ªù–/1­TZŽƒJÓfà–Û1c&Þ\'/>ƒ\ŽÙºp£8¦ÏÀÜù|÷-Wÿ>¤À·FçÊLM‘z²?TóÔü’MPSVÅ/è80M#øÓJ¬Ò”H-pŒƒ>Z@ô'(®´DÜf› …a®Z»ƒ§WÛŒæ¾ð5½ÕJʶÑÔ‚å+ÑÜŠ÷ÞÄþ½L¥H6ËISÐÚ†–6òèíñ8\]˜<^‚·ßÏñWù¨T­Ã’åhïÄæOÐÖŽæqAšcMÃǘc)«^"Ÿ&‚è{#¼Jt13í­©šÇ4φˆ7øry0{.Î9;?úW1<(‰cêTñ~„‚¦ñr0‡¶¹óñ•Û1s^~Ï=ÁRÙl˜–XêëyæYbèØ»Û—˜„ϱ^s|¥&ðB0 ù㻌í­OàÁ Q{Ú@^NB×°Àq&TuGx"Dx•äçî Ç7BGØ«`Hlˆô ”ô‚Eo¦V––V®<_’)¾ùŽA&ËÆønNŸ‰ñÝr`7}‚b£9T+BòÐAÙ÷9o¼•ÝŸË}žó€û|囸j5Ri|º='qómœ2Mvmçhcäõ&òDDB`#E £àJDmuJ,ô‰€SÎÝZEÄ*5:TšR#ضÔ×óÜ à8xöIé9 3¡&×¾õ6•õš:N*eÌ™‡o~S§ã‰Çä…gP©0•ò””ZM‹—¡k<×½ŠB®:N¶$pm '_žPt‚$ìèú—‘Éã^þqՠ͉0ÞÁ–RÈÛn{Ö?1¢* Mi•®ŽaxãXß^5$h¾Ä»_ †E #€n*ú_R;÷±m¦ÒX´DÚÚùòó8~L’I€œ7ÓfH±ˆ7ðô)¥Ûs›yù€ÁÐá•*ê²A´…m££×Þè:âÈ!h4$’JÁ0ã-÷²Ñþ%b­à(3I¾ä¸²ÀXz¨†½š¾‚’±#ö)XiºÎöN)•±ó3TÊHg¾üå B;H‹˜<·ß…•çãÕ—øì@"Bm­X¸S¦É†¸þwœJGŒÕ½ ƒk̓‚ÝIcøk€Øu­#òfDrÀȳ*©h„oîMÃ`Uaä…Ÿ<“í8ޱ:EÁ‚ª/AÐò‹™R ÝdælîÛÃÏwJ2ÓÄâe˜6[7q×”‹®ð„ „ Ç‘R K–áu®Á- M͸õˆƒ§§UÅ…—À%9̘͞Ӯ(Up>F釞¸J˜ÑDš3A:©œaÐýF/SB£¢D\E0–@$ÔV«$iRI Êñã4MeÃ06Zgl1ºÉå0¾wÞÕ—Éö­|ò1;"©´‹†`©ˆdJ¦ÍÀŒÙÌdñæ:~¾ é45MDÍÝÂ"‘€¦CtDèbå}MÿËý‡ç òeÑ6¤Â*õ¸_¨ø­ÐI^‰ÏRsH„#,x¬EÈŒ  ÿ˜Aq‹Š1‘â°Ç¡i`ÂDZUìÞ Ó„®aÊtÌœíÛ°u“+/5&Ò–…ùg¡¥Çx@ºt×ß‚î‰xô!´¶aÒ©o`!i3dÖ\:€üè¹eDyøJÍÓñ UR‹fì9•Nx$ м¢ ¥!òå ú‘Ïy"_|3k§T«H&yåu¸äJô÷ñ‰5Ø¿×åsJ¥BiïàÄIèìB©„ÍŸàÄqd3ªuz裈–ü‘ÍM+¤‡yžéÂÒœ?p„Hš˜I7 Q³ †ˆ„.>±26Ÿ ­GÜæ‰/Êé`(G‡òÎC[liûòr~‚BkÉ"m㤭ƒ§N"7qØ5g-Âîøè1 ¯¿©"UÜNH¹„îIüÆ=xs7ÕJ&pÃ-8÷<¹F&MAKÆ;¯K{'V_N]ñ#R*QÓÀ1re@UpÆSBŽE8$$0àñœG\ϪøŠ`èÊXË0¦ô²¨gˆû‡ ôÓÕÁ¡+-(ßAïÝ~›ŽK®«®£®ËoÍõÃæóhkÇønvv‰¦áÀ~;*…<Òi‰N<¼uã¸)¾7'£ zRD¥¶{¾ÑlD<]ÚÖ—Œ$” )cTmÂí“I¸£Ô™‹w|™›@eÊxF\  UU ¹¾n|(¢ìeQFk1ÀK`7ÖÙ¢Á ÂD›ÍbpÅ¢dë1 |¼A\¤C(Ñêª ÒÒ&öuŒæ°þ}‹¨Tpåõ¸íkøx=¬*Si¾û&Þ\G3ÁënæÒ8°;¶¹R§¢TTެǶ”uêr$£Jª™Ö„[Å7Ÿ ;D¡Ï•DETû÷ÂR_G]q¢ˆ-›½§P*¡­¥² ¦Ÿ\rÏDÀr…fÌ ·`âD¼þ*ß~ÃC(UX_9ópæBLáAnþ„÷K©èz•*ޤ¸²%ñÙ^„Ú} ‘#~f˜|‰D.’{Ðf³eÌüÇ_C‰¾Cw³ ýúÏ<;5T"ƒo#H?Qc4`»]=h¢ùkd0Fʉ ¡&Ï“Y5‰`8o2 PC¹ˆD‚óæK}#×­E¹ŠdBµ0 ÑÚ•2&LÄŸÞÉñpÿdd˜"X~®ÜqíÇú÷±à,¼ø,Nœ@ç8Üz®¿£9¼ù{9 Ç‘`œé^øªÅd†!¥4êÉcù—!Ò×W‡[1”g°1"L>E6ŠˆÚ±ÇËÞöÂÐ ;Ç¡¡QŠE$55V@xõWMµŠúF\z%žƒå©ßòô)™2•-hiESúû°ùc ô£X”Dn3„m»€—fÄlV’I”J¾Ä¢½ÿH÷VMEÔŒ±Ëê^fÛ‰ê)iXRàõgì Wó,"‡N2ÚZpol º:%©‰‰*Ï+T®¦' ÔNðÔ¾Ã6±Ÿð “Dë¸V® ®f‚ŸmFïi¤3ñ¶‹ªUXUœ±_ý:›[ððÏqø Ê%œ±@þêï`xèg(WÑ1m螈¾‚Ë®Â@¿<öÞZG«ÓTGŰªÒÞK¯$É×^Âà@˜Uû4R*ô®øíS‘Éj8me´SßÑP(Æ'GA¶ë(ó\·RÆÈÔXSõŒ ¥"PZ*‰ÖVœ:ÁÏ6£\D2»´m±,ÔÕaÑRÜø¤3xè'²åS::»ðµoaÊT>±›?ŤIà‚‹0s.柉Ïwâé'ðî(y:ú‘åk;hlÂò•R­ð½·Ð?Œœ¤¶gKÆŒE¾„eë95? ªiëzEÃßhžK{8‹À¾½Xy>Vž‡=»‘Ëa4‡bå2láRC5™ ZZ1~<®ºã'`×6ôõqæ, bûVœ:éJ¹„$ïõØ6² ,]Áî ØöFGA¢©×ß‚[oÇKÏC&ª¡?¬7*0$ŽU ûø³àZ;J`ÐO¥p …€k¬ {ñCUê3*9EÌÖFUE‰°‘"1EsŠä˜ RˆÕ «C“¢Òbš8v“¦aÑR9~ Ç"[çb÷]¯_V+´,ÔÕsþB¹p5–®ÀÞ=øÙ±o\q;¿)ç^Àý{åéßB#OŸÄSk0gžŒæùÖkع'OÀå@QéϺ¯>‘ÀÁýüÅH˜8qܵ! pñ™0¾«’Ü(å]иTïžý5{+dr C9“%˜)Xeñ<ͼ¸+õÐé=ͳ—bÞ| J!OÇË„¶ ën;H§Ñщ‹/òsÐÛƒžå‡ïb4çnð4Ü]5óB¼‹Æ&9qœåqÅu¼öFÙ¸¿}Å"ýÖœŸcDR?¡¦Î=C,#€c╜€-0ЀFçM3/pÎ4Ä0)ª¥L<à*&51Щ_ejÉH­îŽ1ø±±£ª#SUßè89ƒ¦at;·¡£ƒ«.ÆæOqò8JE9‘É «]ã±pÎ^ ÝW^ÀÚ94]§F\y-®½‘Å‚<øO]ÛŒt ]]pgœ‰ÛþLH¼ý:*&’ŠÌxÜ¿(RŒ5 ‹­Jè †RåZ’cÐJ$,2ýæ¦áÊSíŸ!¬wƒ½„¨@¨DĶD”×ê(Fn—)RÇFê¦FÌÊØÿ}2´¬ H&ƒS'ðêËX})/¾ ŸlÀȈ1® ³çbæl$Óøx=_zNöïc:íÑz–¯Ä7¿ ÃÀ[ëøÁ»â8ÔÚ±ÐÔ‚Æ& ö£Tt㧇®÷ø_ÁA¬ÁÐjö5ãó}µ~÷q%þ!ÎЊ_7p#d¨k#µc-O +‘X“ÕâFý;dX­bïnù|G!'é¦&\y=ººqò8>ZÏÜtÔ”!€ˆ1‚cuç/ÄÒ˜{†dë¸á¤R2o>6},–¥”5ŒÃ;bÕ‚½c¿Õp¢T<ãž1G‘Š0$™d±¨ZDŠÚ“BÔ/‚°öl-iYT¼kìtP|(å«HvDcÃ<":ø¦Ò®0MÉ óÙ'ÑÒ&³çrâ44Hç8ZUœ€ãøãGGZÛ¹d9æÎÇ©è9 Ǧ–Ûaµ,ã'à¼Uœ¿Û¶â7Ðß'"lïÀŒ™lmǬ9ÇC>džFL™†Övtv¢¡‰½§ñÜ“B¢{"'O•ÎqÈf)ÄëkÑßÑ€sÃ|ç8Î=Í-ž*Ûñ£2šãÅ—aÂD¬}}Ë"5¸*ÐMMœ9“§ ™Ô =Œd 7Þ*Ãxô—ìéA*ó՞ä‘A£ˆT*œ:ƒßùK46á­uxô!ŒŽ •òáœÁKIJÐÔÄs/äÒØü±¬[‹bÙ,/½ßøŽ47ãõWñدË!™‚eÁ41iŠLŽdŠvo¾NÛ‚"x!‘¬:hª¼Ä(‹ˆð`+> ©ž'þšM#a “…ˆ×.£ƒ¬>ø-hÇ ‹®‹8½¶ÛV1A‰HÁ7•V0£L°àˆ®Ãq$ jhˆ™?1T‡ò7 {|Ÿs®¾É6nÀš‡½oºóÒ¶.]MÇ[ë0o>Riär°8–ŒŸ€?û&¯¹…Àã ¥S¦ã’ËdÞ™ÜñÖ¾ˆ£Gðí¿ä³Ñ={w£÷4Ê%×!õ2a"Î]%+ÏcOž{ï½³—Ꮋ0gt/<ÃÏ6#®DFhøç<<»ªUvuã/þsæaË&<øSœ8ŽdR¼½þ86qÍrû]$ðñzärlhÀ9çãÆ[¥¥Û·òwbß>inÛfC£,YÆ•жdÛLšÓ€§a ©•ÍSR Šl¦‚C 0@¥ÜdÔØA ?Œ’ºj2YŠb-`ð¢-ËP†W|£‰àÕkš˜ ² N.z`@Œª6©ò~qk˜Ây¾Çâ0[‡™³ÑÙ…}{xp¿+ãS{½ü¯p‡¦aî||õ.vtbÇvÜ÷¿<Ï/—ß4®K–¡TÆë/á†[0i êÐ×±9q²üÙݼì*Œ ãÁðòsâ€g/Áò²}Þx³æâ¼ ‘LaüÌ=FB~ý pÎy¸æFèÇâe\¼L>ú> Í­¼âj,8K^|Á<_Ó8yŠÜø'¼ò9y‚?ú>>Ù ¶®ñ<ó,Lš,{vá_ÿ™»¶»ÀztváªëxÓ­°æayêwÈåXW‡9seérŽäðàý|ñ)w$RäË2Q/¼Z–´wð;eçÊÖÍüÁ?ãð$98|9κz\yoûšˆƒŸÜ‡—žes3/Ç%WbÒdÜ'<ˆ-Ÿ¢¥…• ::åÚ›pÙ•øt#^x†sçËæO˜•„©æ<Á¢ Á°>aAͪCâ°² Å#…* *ðf•H âÿÝ€F™L c Nm¼ŒHéÁG;6\‚?‹ò}£†4¢âs$æBàøX:*€x†Çæ‰{þ3çðƒwäß¾Ó'©R¹Y3/`[Ô ™s¿ñÌž‡m›qß¿âØ×S• »Æcá"éëÅï°¡ g-ö\¯5“§Ë7îÁªÕ24ÈÇ–×^†ã`ÙJÌžƒßçÇaæ|û/°`‘lÙÄÎ.ìÙÏ6‚ù ñõocêtœ>…Ùs±æa`âdÜt«Üz?ß…Û@¢ZnðÜUøÖw9qÖ¿ÏþÇ@Ç8Ü}/&M–}{ù£Áç» °m,8KîùKÌ_€íŸñ‘_ÈÆõ„¸GÜðŠòàýxþ)êf ã."Œ¶F:Ž™–ÅñÝüö_bÙ9x}-ú)Žƒi@Ét½!„»ú¯¾žòU˜ù^} õõXx6–,“iÓ10ˆÇá;o ['ŽÃ®ñòÕ¯ãê¸á}ùø#žyz{ðÞ[ÈÖ)Tg¥9/ö¨TQ…´Ôb‚†ËX Q p¨¿ã…VÓ„¦Hgü#Ág¡Qõƒ©‘Ÿ œƒ\ âÁÂ*¥âÅž¸J¹&Ã$Qሠ©Ó4LœŒæV’΢­'ŽCÓà< 1¯nñª2eîø:-ÆæOåg÷q÷Nè¦wiug,À¡Cܺ º.3fqÉr>ˆþ>45ẛ°ü\‹|ô—xéYŽ ã¼Ußu¯âð!™<w}+/àà ·mÁëk10ÃàÔér×=‹DÒóËçCéøw¥„u—ŽãPÓ0e*îºGÎ\ÄçŸÁÏ~,¶…d’Ñ '"ÈdDÓ±`¯¿Møí¯åÅgP©pñrLŸ)&£¹ü¯¯•L–Ù,ÛÇáò«xíMØò)>ÞÀ¦&Yÿ÷íáœy®rf)V”aÔlGÉ%xüºêGŒ6˜kµ2j¤—"è#0™€®H$áÏEÈqêX©ÝŸ0ý—P9·?hè~«}láG´ýTy؆±o6}Ì·^Ç‘ƒâNU"$tžÎÅA:#‹–âú›¹p‘¬}¿y˜GI"á"ÿèÊý½þª¸°­Ö6^q Òìùý˜5sæÑªÊkäÅçX.Ëâåhlâ–Mrô&Mæ½… /Á‰cxô!¬}ÉëTN™†{þœç®ÂžÝò›_ñ­ubèlm“»îáÕ×cÿ>¬ù6®‡ibÆ,YyW_ކ¼ü<îÿ\‘‰“ùõoɪK88€ù¿dãzÉf9÷ LšÂ›þD¦NÇë¯ò‘qèMšŽó/Â×¾‰¶vüü>>þ˜¤3˜5gÌGÕ–O˜Î j¡Za¹$££ÈçP©"ÐT…ÀqØÒ†yóqÅ5ð{ÿ€m[D×i¦L¥ãÁêeþ-A}^UžxŒ¥2Vœ+é4ÚÚ1÷ ®}Až{ Õ*'LÂ䩘>ç­’·ÖññßÈ¡ƒìgS‹,^ÆŽlú$Æâ " l%I¿ –©Û0ð$r eÉ‹où¥Š2ùC2‰Dšn@Á^Eh0 ;â‡j”ô}¼Ê-ŠIÞ©‰5|™§;4·ñsè>ù۶Ȧ‘θæBa8 ÀnMÒÔÊå+qËm¨¯“GÉžÁ@Òiè80 ™9‡Å"Ž€dK–cåùسë^A*K¯ÀŒ™xâ1<¹†å–,üØò±ìß‹ŽÜñu\x ŽÁ¯~*o¼æå &ákßĹ«°~~?Þ‰2¹èR\q öïÁ}?àÆ hjÆÔé¸ü*£{Þü=øw ÈdÑÖÎ;î«Q*âþæÌÖÉòs0a’´´¡©>à/îÇáƒH§a&páj|ó/ÐÜŒŸÝ‡'‹†F¬ZK.CµŠžÓrö&ò£(d4ÇžS8~ý}(Œ¢XD©$†Îºz,;]*ï¿‹g÷de0¨+Â%Ód[»L™†ú:XæÏ6á—?E>‡• ®‰fÍÆ§䱇1<„³1}& ØNç/ÀîÈd¥³‹ËWRÙ¼‰¹tqtXˆ©¡8û}ÍØx—TÄ¥DÅP™†…N•êœHB× U Nâó§8ÁÅ}!cÌoñ‡år„F"‚¢^dT¤¿©ªc]Çþ=lleç ÁŽm®Í·§«ê¹¼j4 ttbÊTΚ‹³—q×v<û¤lÛŠtÚ·§', ]ü×c˧øÞ?R×°|¥Üý] `ÍÃøôcœ½D期ᓿe¹Œ+¯E{'׿+»v°­ßùk\qìÝÂ÷ß¡iÂq0~î¼[V_Žm[ð“ûøÙf2(•ØÜ*—^Áß•þ?Áä)²h1ÆÇOï“?ÿ/ܵCþýûf[;æÌ“+Ù×#Cøé}òî›ÌÖaõeL$åÙ'ù¿’“ÇøðÏqè²õhj’ëoÆ-·ÓÐñÐOðÔïÐЀ›ÿ”]ŠÇÆóO{9µaJc#ÇOÀô™2ïL\w3›äø~¾û÷²¥Ófb÷Nù¯ÃáaI¥`&BÞ‚t hhd]½L›Ž“'øÜSøÛÿ|ý½¼è2ÉdñÚ˼õv4µà?~€~,[)íí8r§NbÒdùð]=‚®nL˜„ùgâô)ìøŒýýbš€ºtÆP‚ ã %¡ Q+ûãgÕˆè¤Fò>ÿñ šn¸lF Æò•À0‰Œ“˜ýF»&†ŒD…¨D>F1aq|G$ ‹‚ø„ØŽl߯rEZÛpîtl K~Ôc«$“ÌÖ!›‘¶vvta4‡~(;¶±j1›E €åþÁö©TØ×']]œ6·ß‰Cûñôïdã‡pl¶¶£ç46*™ VžO]ǯâжwàîoã²+q`ú>|O Ž®n~ë^\r%?ÛŒŸÿ'¶n†ixLž>…W^¤aʒ圿{vóµ=C—žf"‰©Ópî*üùýråuüø#ìß‹öNY}Â'shÉ$?|½§1¾[ÆOä_áùÂväÁŸâÕ1qžÍ®n¼÷6NžÀ´Ð5¿Y äG±u>ÛÌ·ÆË²>jåù0MÙ¾†eç`x˜ÕªØ­*t‰¤è:IÔ×»ìPnø=§Å²­çöÏNãü‹P­ðÃOqê„8öïC¦ç_H±±ý39x€ãÆaxˆ™¬,?S¦²jÉŽm8t@ŠE˜&c)O'* Ø÷‰z<þ!Šmˆ‘¨ÊXTF^@&4ÒùÉàч˜LIW*¡ ¾¾M\±™"âµAKEåŠhÑ)º 1Òw1ÆdHØœÛ-yY.KK+¦NG2 !“I„Q­"F}zz±é# H*ÅD¤'ªœŸ¶-Ù:Üt+–æV,YÆðÂÓ(%›EµÊYsä¬ÅÙÞŽÛñÁ»R.²XÄ-·áÎoa þ>Ú,¸æÜûרµ“¿øOÙ± ¦éUB.ìtñrœÄÁÞ=xå9‹žÞ÷9çbñr”JhïWžÇ¦O("ËÎá’å(—Aâåg=»eaŹ8k1òyttBÓ0ešÌ™‹gžà‹Ï`Î|™<)͟rÞ|¬º“&CÓ¥‡eQ£Ø¶—ø bßìØŠÓ§1¾ ÉÂEœ=GÚ:9Ð/ƒýÈ嘤Ò4 ŠØ¾ÞÇð¸Îª¥’œw:ÇÄéS²åSæóÐ4ÌšƒYs¤\B_/öìÆè( ÐÖ&3fA×Ù׋S'18 n"*ùÛ†ˆ¶W‰H¤%ù¥Üê¨&SHo•€ŽŸ>Lç7¿Âþ¾NF;¬9UE/úvÙ¨TD£3ÿ­(˜I¾ »JT {~š/‚+ 4“’Í"•¢ead¥‚·•\=ZM‹ô”Oâ8Ô L™†b'£Z…®yÊ..Ö·­èéÁȰÐôpzø™F@]„¸˜Maù÷Ìe“‰Ëù™š†öN@¥ìAáIL˜„ÜFG¤RHÍ/:»P_Jw| —_ƒwÞÄö­0Mì܆íÛ`ùÔXM“>¸O÷ †ZI¦˜Í"“A:]G±ˆÑ†`Û¡óˆæÓnÄAk;* yÆ0n šJC#òyÏÜŽô”R)Ñu p /ZÐÀ•ª IDAT“U±[Ži "Ëéÿƒž€P ™D²‘ñÝüÉÃ[Z °*ý0¢áCÛÕïG„R'¬ÝýA\’@á ãÄÇÈIdZícÝiˈH˜®{oɪrp <ù SAmÄI!=ÚÅo‹cqÏNP‡F¨2!î½=è9 MsÑlQ©Íi+X°+T©ϾYhWá½LÌ+¶“ÇýLI#4oï>èÃ@4ò* &½=æwÿ«/Ç¡ƒ8°ï½c‡¡®QÀY`üV*ÍL-ª¨%¾&öÐ ü碻R]ОÄ5(è]UòVÓàŠLêzÀÛ×¥\f ^¢?GhŸ‚¿Ôf©:Taàä~\a|WÇ}jF{‘šÒÎ.ÚNŒ®íª2âL/a\˜mû…¬(p*~µÆ»·"*Ö=ã)Qý©`ÜãcMkT!ýn ŽP ¸:š¸5©OzËE×Bm4•‰èზ%NÛ‡8Žgq'¾†…(âÞ‘'B¨\†à× ÒÝ`Ž×°Êd©˜1“7|‹—áéßáÑ_ÉȰgöHÖ°UuMÝ #2SI4e”˜îB&R(!´R×BÎâF€ŠévTUŽ‚¢{aS©Xã(z&:Ëøÿ(e–ÄÈ’V€Åî_6MhšÁ–V±-•³«n¯ÚÖ}\=KIlDó™(jHÝ7ô¡âEy³ŠÌà˜¸QUö(ªB«´›j„aŠJTFÕ•vÉêAí/QH}L&K­ÂB¨#*ôÙÕpÝC®xÙ-I æ84 d²7žgI“¹|%Ú;ñë‡ðÔoÝÕÁ3ˆ¿ÂN%¢¡¢ê0Pb`PEþ@¥“0v³\ðˆbùCÕy#¼…cfš‡‡qeOsˆ´ îK Šý"úIÝk;¬*j L¤`DÜtMTT…2]•µGª­$eÓyQH”¸VøÚâ½"Ÿù×êü¼IG½|*C•/_a¯ƒj!õ‡.~\šªB²ÂQT´CG-Å.Qjh^cõE=K«ØsB4¿†qÑA†Ãàa ™B*…TJL‰ÇuáÎoPF†ñÆkèžMG*…Öv45¢\–ü(7}‚ü¨Xû{Q­ÊÈ0O@±„jEJ%ó¾È ëtÞé ù3ñE> „ÊGZý¡¾ëØþµ”È 5Å÷Xw¥vÕ2öËtFššc.9‰«…~™òëC?Öi¸p5šðöëèëE2‰K.Ç ·Ê OsÝ«(—"½—±àÐF)ήŠö$fšÕTXÔbmlºêX¦¶šJDòŠc†"æ€^â (‰ù‚QÏ@EüαáÚ¸öô¦)¶M×÷-“ èî3IÓ@S+Ò)1lhÄYg#†n ™„®£¾ÒsÿÛ½ÒØÌúz46ʸn´¶ñ’+ i0Œ€W ££²ã3´·£¯…ÜÝéº+^Ââ«åHÔ @”ã4`Ë«‡DÑ[Yu2Ö¶PWP-ltDÚ !¡<&M¶O•ižDiµF@ˆÌÛ3YþýÿŽ_þ Ç![‡;¾ñðÔcضÕ[ͬ5ÊŽu¤Â¤ÓOÏB=U5GBûî/ ±Ø0¶i­Ä7H, `0ñ ëkÿ§õpq<–³cÃvgŽgKìŽÛ f™Œ …B[;&MÁ¤)(—pè@44J[’)I44 „©4¦Í#‡ÑÒŠ„ÉÖö±:Gýò­¯²¿_LƒÉ$²u’Í"SÇæf´µãœóÊ ‘€ibòÔÈ~P?¤©™åD¤Re±à¹Ã»Ê"°lØUŒŒ`hPF†82‚‘aŒŒÈð0 £2šC±ÈrY*%T-W¡)ÔØ Ê¡@èzÍãC†Ú¢KÆF\nÁX42u1PQãÒT‘EÔØÿ¢F®"™ ÛÃâv)”L:"ÞØ(·ßÅ];ÐÔ$'óÀ>l\“'<¾oMÔzõÕÈÒ×xq…DjmùWL¢Ö•µm"UÐXj,š)êÎåXtü)^ç÷4EרbèL¤$™D:Íld³lh”ú64¡±QêØÚ&uu4®9§7u†Dé Òi‹0 „š àCòyŒ ³TËbs3Ú:(ÃC¸÷.9y"ª*Ojºh:³Yih€a2›•¦&6·J] S(hnãò•è‡ÿO®˜ú…zWÝO–íaw yÉå0:ÊBùQŒŽ"?Š|…< )P*±\’r•«U©ViÙpl±:¶8Žwª(òÓžúN„õLÑ|.C@rg™¡ºm¾ K:‰K`!Bw¯my †w ÐÑÉSÑ×/dzR XàP½áU°T¬N÷…¦½ßeo¸îÈÞ7¿ß*pM“ßÍÒ{NTèØWf†F¡îjÉÀÐibH¤˜L!•D:Té42Ydë¤.‹l=³Y©Ë"Sl–uu’ʰ­ÉäìÌøµåMê‡ Ühï@~TFGQ*¡0Ê\ÕªFY,Š ÷,1Ø/}½Í¡Pr‰•²Ü|/½ÒˆÕž¡A€mÑ®Ê@‰}ÞnÐ0APבHâчH Íœ2¬ ‚t^8v 7ÖÍ%UUý?êìþÿÿš…Èx@DVyÁÁ‡e…£h÷·l+¼êÛ¬VÝ„ Ž-ý}(äY,¡‡FL™‚BQ ¨VA`t”ålKFr|à>LŸBzNƒc{²v–Ûvl›~ÅHŽÕâuuâØèï£mAÓÄ-K‡D€2D”ÅÛ á¾Z0` •Bc³„óúˆÆ*×)ÁײTÁ– ¨Tqù•¸ì 8‚3J¥ÊÅKð?dC#lGl‹€Š÷K¶?ûÄAnˆ–%ƒ% ¼ÿ>TÊîQëeJº!ºA]‡iJ{+NG¦NL5Õ2Ì*eTÊ¢›^¾[©0™”_ÿŠÉ´ q‹§„I3!®– ™€aÀ0ÑÙ‰yg@×Q.sÿ>Ý|×Ë" ]4 šà¦A×¥s“Ie¥,®‚¢FêºÀÕð L4:¨}Ùª¶l_V,~)é¥OnÚàlKl‹¶#n†æ8nÖ'–MÇ+ oÛ°ª°mZU©Z°-X¬*H,XÛ†íЪÊK/Ò0¤ZAµJ«*• ,‹Žƒ«®–t†ÕªL&qò„¼þ{X^æI/µQ*ÊÕ×Ñ®È@?³uÅ49š“buuxègÈ`Ë&@¨é* ŠþŽOykÞ]léÞ=¬XÐó4JEHÄWÀ¯˜)ùQ¤Ó¬ZH˜Šðž:- &ŒâArbYìîÆÒ[žø3Y¿°ö›Dî${ó'¸úZY²”š†í[ðÔ“¬Tâ–×ÞÇá‡ïÊäɬV0<ˆl ¦ÁŠ.¿y„ƒîÛË?µ"u}𭄯6 #úºº:üóÿ”ü…<*5 ±‰?ü>ÌDt.Ó‰@"AúBK/]t7€Øv¨^È£Ê@MýÁ:N õ<@Ÿ(¸ V«Xy.¡ktl…¼è§NÇù«dë_rÕÇNÕ×#Æ©ã CËBC£¤Ò¼ùOÐßÝ»Tí{¿‡;À7×áâËP© ˜Ûf©@Ò⪣Ñ40œçkäØ1¦R^—¦RASZZQ)Ko/Ë%1!”@*JŽ ½]:Ú1{.6nä©bÛÅ‹:uMª•@ΦVÎÛûΉcx|?u 錼ô"—-‡cA7ÐsŻ…c3ä [õí{eÂ$˜îûNòÐà~ÂJÅ=X6 ij¢¦¹VXì•={h[L¦¥T¢iJÈÕò ~÷˜¼ð¬ª8ÂT*°ŠP}‡¨i8zŒCC’J”j•==òÚZ:HÒ•é 9E«UäÌk0cˆ@á\,øOßÊ•˜0`í+ÒÞAWGT qè+ªMÊevtz'MSaKÔ**“¨å–^ë\ªUˆˆ¦Ñ0@ #ÃÈdQ*Šãб lK–.çî]®ËH¨æp⇆<Õ®¦&5 ½=rõµÙˆë™Î„Ì7Çñ…˜5ÑÀ;ïb: M—é3ñù.>ù8ÒiïØ//<Ç‹/Å“O(Î 1£kÇŸHA4™´W“nøPÎZD3ÁtFúøÂsâzpÝ#Õ_qÍ-hnÁÈh/¾¿ø™Û'ð¡… rWÑÐ–î ¼õOAu&¨VQÈcÍopä§LÁ…¡©½½xëMöö¸YAD/±¾€x( ‰Îð$G¹„Ÿü˜^„R$6n`±(‰„ª³…úVÓî[T*ƒ©×MïDƒãàÝwC÷ Tå n¼ç] –í6ØÞ†Ë.ç@Nœˆ˜ïºo¸Z᪋Ð1†!šÎd^¦Í@[;ó£^ÐinÆÔéxû 9ìö©B5Ãðî§C86Chœ‡Îòþ7Þ,'Oò³­Èd©kÊ-‹Âl‡Õ*uš&~àˆ „UH@&SüÚ×}0 ’ÙLßúz{0k¶ä á¸ñ8g%¶nÁÓOù-¯(¢M±²U $È]H:޼ºÖEIºš óW†ý{Q(Ð4=/™DR¬*³u˜=_þî¿b×þþUæó!JñÝw00À “P_Ï¥Ë1<„RQlÇ=XñÍ& ôôÈM· £“ɤ|ü‘lÙÄ…‹ ÇæàlÝÌ“'ÄË|-­Xt6uBäsâ*ûÚ6§LÃñã¡uP¦ NKÂdÕò$…›$™”ü(@)—ðÿ[äìÅ<ãL<òKïz:V_†™³ÑÙ q°¿œ>ÅgŸöœ TŒ¶v¼ú 5õõ~ŽÒ…¥É@?Ö¾Œù ÐßÇ×Ö¢¡A/sçhN $R€ZJõ÷Ê?Ÿ©4ÊeØU” ¨oL¥™­CW7ûY­ˆÛÛ)—dÊ4\~óë$¨ó<å¡"[qAâÞeCˆEtTÐ*b–ê÷wuÊȦNÇÔ©bš°m=ŠÛÑØìq}òy\#柉DB6ÊW×B÷¢Ae¢z.)ó}„'B8hj7Æu1ú°9B#Œ˜‡G¬wX*áªk1aN G¤®Xu¡¼ò?Ù(Ó¦3•A:#•2A:Á~Z6æÍ—™³øO’iºÇ!;¶cÇv)•°áCÞvl <ŒBA42ôÏöƒÁ¯×°§b˜\ºŸï”þ/d³AÞ,©d„’L T†žód&ª¶¤RL&ÑÔˆj‰$à(ŠØÓà¾}°mtMÀ‘ƒL$…%f2èG¡€;¿Ž‘4µ€”î (PWÏ“'ñ/ÿ*†IÃ@oR)47³±QþáùOßccc”lí¸âjXU¼ô‚d³Œ©Èûk…èšìýœ{>é”KÎråîoa×N¾ÿ>ÝÅÇjW]ËÎ.)æIH¹Šd’ºNG¤¾ÁmgI"‰áajÇ·矉å+°u Ó³(.– 6Sé8‰)¢@¨žY–AÄÔQu€Œz…õŽ ðªkqÑÅÈd¥ŒóΗáõu4M á|éŒT*,—åŒùH$ù»5nÚæSíÂi¼åV*Æ@5Ú¶dÖ\÷û\/“1úæþ¦§b‚§Òìí(±t úa&ààH\z9‡‡ðÚZ T‘!d²ÌçÐsJú‘jfBþæï84à»d“Žƒj•-­q*¯žPëÊóäà47£Td>b3ç`ÉRw¢äó>„E€e‰axŒ[Rš[ØÚ.™:Y}.¼VUáÓ1°\‘ƒ{a&$?Âr º&2i¬ù5<¸K]¿yÛ;äö;PWGÓ”JYÜ+£éA:-+Îm=(ilÄ=÷ʲåXºLþÿAw,ª T²¬—gjZhªmU9k6¿ÿCNšÂ«®Å~$Ý]/^ÎÈÐÓY)—˜0™LÂL¸®²H&¡‘ºÁúq|»[ÛÛÆü…R,¹3éÏ?ÿ þý“•硵VUq—SŒŒÎ7¢RÊ!MPB÷ Mzf ¸|V](Å’ë] ÃD©Ìå+8a釆F˜ Ú¶86ÁÙ‹áží¾s$£Ê;“ªD¶«ˆTmΙ«¤@™ ›0T,}ˆ¨ÞäË -#•*)Á(- Ž#ºN׺'›•b¿z\„Uáô ”ÊR*RÓ0šC2 €­mX~vl§®Ã¶0a®ºZ2uÔ5T*ÈÖ¡¯‡­Ç¦M’J…¯P7Ð9É*ˆÚÐ4Œ rÉR|¾Û „*EÈ}¡½½ìíEw7t¢épd³8q+VÀ{ÚçŸõ‡âÈ!´¶Êð0t]L“û÷ÓÐQµ0s6r9Ô5bd@*U6·ÉmwжP,!™‚‹tÇ%šÎbA–,ÅÖ-•DÓQW,¤Z¥®ËÍ_ÁïÖ0™ ú‚E¹$ɲYÚ6&M–o~›Þ©?8Èn‡~BQ8@œ:ᱫ %°¾¶õÿ²öÞš•å¹÷u­òö]gOïÔ@º0¥7ibFcbIâ§)Æä“cL8Çœä•Ø ±!HTzïCg˜Ù³göìòÖU¯ïµÞµžõΓ¯ì„=oYÏóÜÏ}_×ï’mÓvຬVÑé¤>'ß×’ÅÌÏë]ïæñKN‰‹kã‰øÆåh6m_& ¾e¶°Íë¹7B™[39¨£ˆ§Ÿ¥n—åŠz]øÊeIB}Œ®½†##ˆb~ú`:¶ju„;GŠpDÓ>–¥Jõ»X1ÆÆ‘ŸËW"ŒŒÇ%S?AÉK5yÑo\$4êxæipÒbª^Ƕ×Å„¸dN?a–*ò=*V"û C†Œ ŽÓÐ'>¥Ñq®^«‰E\¹Š96®÷~ë×# IœÎ†z=ű/Ç•ãʲl™>s8yŽ‹Ÿÿ Ž£D’ˆ‹vOC±¢H¬S¹ÌÔe1U4 ßø6=Íáa>ùÿìÓpÝ ¯ /VÏÃŽ×9=^%€Êe@jÍ÷ûbPÒ²GJ%¬\…‰…¨¶£n›Ž×a«iÚLå§A?л.Å/ã%ïBÀótÚ™œ™ExžÚÍ vD˜P@Áu… |vZ©R.ŽA‹í¶B_I…(Ö’eˆ"z>.YÂãO„í¢TfHb¥ÊKÞ­ÀÓžDÊA3½ÒIE~9O¯ÂTÉǨÖ8:ªJ•aH ZãX'œÄ¹YìÞ-¿§8êó}mÞwO 4™O„%¯ óYÅB_¡d!AvÛY¡@fYôÍ¢yˆuÖÈl ¬ÕuÝÏ™8Ãì´tÍOU©hñRüég1ð•ì÷Br©e)Žá÷06Ž8¦„#ŽÒô. £5ÏD§T®¨ZãÔœu.J¥ì­*šMu;öz¨ÖàºØ9Å—^`¯£Œn”¹ò’ï(ÙGÿùŸøÜ³ ú=µZìuQ­%2!Z–l‡ï{¿>þIœ;•¤ÿäÇøìŸè†ë±`Aß9`àL¦ÂRL$ÙubæLíC[TopÙr|æÏñáâþˆú°Â›_ÂÄbŒŒèµ×pËMéC3,°O[Z´ˆS£¡ã6rãI |ÎÏÁ÷Ð륌ëR®ÃJÊeÝz3«U%D*Ûe£9‡Ns³ê´å{ì´Ùë°Ûˆ’Ëé]h éñGǺàb´š°mx=><Žƒ+Øíåqb†› éÖ¤/¶ De†#ïsñ“$eºɲ,—4?ÏN;ݰ$ԨׄHŽÐùŸlµØÆØ(^x×\­z½`›1÷gäD™p”…´z­q Òöm2y7ùêfE'2]ö‚ؚǗ/Ã{߇#ŽÒSOâÆë9= ÛÆ~ûkj¥Šju&tžñqv{"Ùép|s»¹ý ÙvZß—«êõP© ×Cb`÷{²,–K\¸““ýè?êæø7‹ DrnÝ6–,ÕÝw¦—–  E9‹|ùÔ¿vÕøæã°kWJ× |8NâRàgjÍ>$54BÿþÕ¬–…JÚâÈø¾¶­(L—¤ï±1„(âð0¦wÉ)@ÀvGÇèÓ—°È IDAT"©×a©‚™i,\‚SOÓ×¾‚}÷Csj\·Á38°R*.ð=,\„§Ÿäаnº‘ùWš›#ÛAè+9ùh‰`­¦o}¿ÿ1Îͤž8FhÇv.^‚é %ߣë0–¥I»Í[oF£Žvq¤N› †¬Zr]Q˜™9 ›ÌCMÛ'ͧ)nròZ^CIŽÃv€cɱÑiƒÄcwkd„…úêÿæÈZm²­^M¦{Ȭ–Úƒ.'€ÝN|K~¤×€>Œi½dJ‘¤ó¨#cjmôJ%}çÛøÈ‡øÍå쬒x§MÛaòÙY6k5Vjj4غõðzõëÛ鸤…_€ã$z¹Ó÷d»´,…‘?­*’Û°ëâ¿þµ¶¿¡Ý3ª742†™þÕßèÜ·iýA¸ô½8õ .^ ßÏ(9/¥ZÕw¿­R Q©Òv0;Ë›o”×à '¡ZE ´l™fç†H"™„ÜP.ã‡W±Re“Tµ†0TàK_LoaDÇU¡VgµF?D¢\ƒï)ŽQ­rt”Ü9¥é$†º`ô¤LÚ+Õéðg?Ñθ槚›—mqvF¿¾Í&Je(Æôn~÷[ ‘IûÊ+¼öjø>*Yäȇ†Ùíâ7w$“>–«²ØËe¶[øÖåI.¥~s;,‹Iö8)¯‡(Ò¯nãðpÿv’mô}"]m„"ŒcOôUò fìÙäomÏ=Ã(@¿ÀXò}xú©Œ7ÌrYìÄsËARSzبdS&Böí«×C©œ pèÒ·'{0÷ŒOøZöðÔÒ<’%ÖšWbhŽCAc£üäŸjn†µ†FÇ@‹½l'ý=• ¾úÏÚ¼%Å‘&ò`å*9.ýü¾‡8†EýÃߣZ5×½$v»8ã,œxÂPµ|£c$1?'ߣ[Â+[ðO—aé²Ô¬”MJˆKcÝ:•k|ãu½ð“ÀÆ'àô3“«¡hñÙgðÊÜ}'FDz&½#!W­Ä»Þ+ˆÃ#rlüã—МC¹Â÷ÿž-b£\ëbh¾ÛVÒ÷E²‰_¾ vß65 æ,øÓH¨Óåüÿ—šXÈXƒì nŸøcŽ#À•ʈc9ææR—fµÎ­¯êÛßdµZ´ùÃPl;P C\t :¥2ægQª@‘ü_¿fÎMNêE‹xÆYX¼X×_ËÔÄDJŸ™Ñ›Çèc)Šùî÷ɲéØêv©X¾Ïz“¯cëV\ýc¹%ÞðBe™`‚@o=•^¬ßÜk®¦móø4ôÏ Ì rdå{Q.C1háÒ÷àÈ£uÃÏù³ŸÂuÕ¢c÷b`ñœ{žææà8üö71:*Ë2FÀä +‚f‹ÇÖ ì¡{p,2!wNáœóxäQpKh5uÅwèûp]“f` ’Y ´¡ÚÑÝ]¾‡»O^Xÿ06Ž8ÎÓ%͉Bž_f¶?¹“FèècqîÛé{p\|©ªUù^~I¿÷ûC³IZðÍ„ìuP©Ò²P¯K v{8óœ;Ùdà1©nÃmàë[ḦÉQ„%K°ly:"q]Ù6l›vªuKl71>Á‰…j·²Ø¦\ýmÛfÂÙ6¯¹G…¹Y¹e>,‡ˆuꩼáç3q«‰ÿò·pÌLãM‡cóff{ùø87¿„¸ÿLï·>R:ÒV ß“í@1ƒÌÊÒjÔj8òH¼ñ::×_ sJÐ÷ÝJáKå<ÜgÅJìvìà¹oÃÍ7©Ñ`¿Å¡,SÞuñú6\ñ®?H“ÛQ.÷ýzDÔlDfÜÜXjƒÐˆ½¥ÁåºÀ…‹t׸÷%&¾jýé²ÑtÏç(™‡Òœ›˜³Ü´¦‡aøFŒµûeŸt_›^o$= ñ¥ #1s|çrY˜º €ëòà lÎËïavÝ.ßûÎÍ@ÉUÒëÂó@K~O½l É6Voh~޶¥^ÿåoõÎ ûÐc¦&‹ŽÃw¿¯¿û&—+*Ž1±ŸûkN,Tc(qÌ0ŠR‹ï%mx¸eA(—s,^ßbXX÷´0Ä;/Ò®Z´˜q߇EÙ.÷ÙW–mè‰ àøæfµ|%3Ã~¿' Û†ëÒqaÛˆ#Å:->z†¡\—‹ó®»P*÷Uÿ}¨Ã`ä ŠňcLN*Šûö•¬3!Z!©@¬èÿú„¨ÉI´Û 05e@íDáô3ñ¹¿Æó#ÃI'Á÷Y ö'bÆ‹”Ðé Ó…ï+OÊÊQøÚT åm'<‹rY¶rYµY{dq)æªI±Æ(QFNE&3”Ô….Ž8š½jµm|¶6…=Pý…RŒ©NƲE2Œ`Q½.¼S‰ Úº‹¤˜¶ ¾¯¡vÚÚ=Ír?÷×§ç£Ûã ŠrñìÚ)ÇApÉLíL³ºE6›øƒ?ÒÜ<Ö%×e‰d©¬ùÙ´;ørKT,×…Õ‘•ù¥-×- qÇá®]ð¼$Ž­j«Vã…çæ‰ccøúå8ól¾ø<yQTd ÁæÜÏýÈ8JîôŒc¼ôÚM˜(ÔVš3¤râbèãŸ.ÃI'ë™gRGò-„!–Íry¬XÓÖÇAŒc†}埱þ`nÚ„Z-•îÀãMîfG ¯0ä›×3ϲÓ@ÒÄpûŽ8R'žÌ…‹ðü³¼ï¼ôRv¹/Е‹¶‹Ãbð#;çRÙ\ÿ–#¯ 3c/¯³F ÈR¿ ´þ`tÚD²iðýY̯¦²Á‡)ðtÚe§†nz>¢”¼ Ûæ¯~Ûb+G$:møÆåªVuÚé¨TÔíÀë¦ ­8b„‘ju††QoÈŒSXº  Øi+Žéy }ˆ½.fw³×c©$ ž£RáΩ¬'T¤ž‡]» òËÆ¶mˆÂdÃ#Ÿ`¥‚K.ÅYç*™R<ÿ¬¾ùuüÛ´ù¥d+3Âd ãÍŽI]þX´˜Ë—kx›_Æw¾ÏWÂö3áyŽ! X6JÜsæç“Ë[ò)ñÐÃôáêmoG«EËNN‚A@oòTÅm[k÷A©ϧדïõoêïýÒŲP©À÷…´(õº‰Ëž§ô c¸Nç½!4ç±p!Þ~>V¬ìw(ȘàÕ_Êo*€Áe¤zdÍͬn+¸x4;,ýD ËWž Ŭ3çÒÌë²Múf~ rl}ç[üüß T‘Ãuyݵ*—²U*ÇåÿNŸþ,K% f¹‚v ?¿&é÷£\U0Šá–¨( CÙNR¿¢9'ß7ûËÚ±““ÆŽíᬇæ<†Gd»´CHpKˆc4ºÿ^¶ÛªVLŠ@ŽŒáÈ£pþzð>Þz+vNÁ²hÛºã—<å4D¡â˜É%¬Ñ@‰·áþêy ,"ðEÒqÓY^¦¡($8Û||ño±`BqÄ8V«ÉÆ¢FJ¬è„Ìö©L>—¼ 3»±ý ¶Ú´¬ÜíF¬VP*ñ˜cqï=j61³›OËDÛÂÜ6lP3ðQ©¦‡že%g·êu~ÿ MOgXs¢Åæ¼î½—CCž¾ßÇ𰦦¸ýõ¤-AÃîœO,Q„ƒ7 Û•ã0Ž`¿ý¸j­LpåjnØÀ(Âö7”È ‘E’‹ÒœhÆef[e¹‘Œ“¥ÀïQkѰƒÀ)g`ÿ‹%Àñ l}U°²¾'ºæ‘gJ¼s¿§ÂlÂ.ÎHhñìó´};·m•m›a^,Ö6ntÎr4( F‚AîÉ(ù( Û¦s÷b¹Ì¥Ë/ÁT©A(&á·Oè,ŽÕ8à-3QÙ‰¹mxÏûa;H,¿S;õÞ÷©1Ô7I+U|ýkh5Q*‚×…ï) ð·+¿‹GAcÈUÞ)p¹%x]º%”«ŠR*z=Ìì†ïÃpÄQ8æÍIµÏµ4ßD¯•*‚@¶Å©ŒBÌÍ2ør]•l:®®þ z]¹eŒŽêŽ_bjtÙè¨z]öº”äù¨Õ`YrK{‹Ÿ “Û “PccxøAØŽòœ‚\Õ6z ¶¼äžÚø çWþcñb,˜Ð5?åÃÁÌÉq]ÂÐ0ÚmŒŒªÓ©ù9úž†Guìqùý*ޱÏ~œQrŠÐB)±A÷¹öÙ°ÕŽY©âûøƒ+ñÝoc÷n¶Û°D½^"CB»É /‚çe½TåæE?3Ù½ˆÜ)œ†*˜s¥<‚%k ©˜êA¸nbtÞãØwÜww‚­(r…r'9@`èÓš]è¼JTòÀuu»´m¶ÛˆBÔ‡¹f žÞ¤Ô,‘ B|ù2ž÷6-YЉEÚú*o¸.U~&UuþigS§Ë—_Ôúƒ™à¦.b¹‚ÛÓˆ ®Ãn眫ßþÃ<Œ3 uÇ8æÖðAÚ¦ü²Ã,/Ø´ ç™}¿‘ñž|\qŒ‰ „ ¡8.}/I­a& Lžêáaüâ6&@Ï„’™Ù>sà7 àrY×]G 'ßC£9/Çaà#Š@ QÛAqãF<òp:Z§ ·ÝÌ'Ãb×.¾ü’Æ@‚E^ÿsÜx½ ”JP ££|õÕT¯‘9_/Á×¾¢÷¾Ÿõ! Áóðý+4?ÏD»B#¯õÀu:ç<÷<ÜrKæ°0FR´YÚfÙzùiô#ßz*Ï8SÞÏ[o釛îX€P©Ä{ïÁégp÷¬,0޵h1ãl—/<ÛÎ6J Õqí5xê)l{ ƒ–Ý#óF'³ŒºBh¼’,UÌŸÒ¾-ô<3Z&oƒbf7ïºC†z4ùìMO3 Iy,4›ó /¹V‚å2žž‡Fµ‚÷߇'ŸH^ Í´ÑNÑÒe¨Õé8œŸ‡ë(ñIïÚ ºàb&îÛJ•Šh;ˆ¥0 m«=rŽË'žà®)Ym›Ÿþ,?’ ù¦ÃqÂɰ,¶Ûlµi€ ô< ‰B$ƒP¾GB¶“7›ã˜‡ÆãO@à³Û嫯˜Ü¤œ,†<ñ$Öêò»ÆÚ}q‰PÌg6±T‚q fKó\(¤›{L·§·ŸÓNçü<-ÖêÕxð~º¥‚D§¯¦f»…R«VÑó46Îz–•Ò­›ó8ù­xõm¥ß¿ecz§î¹›?Ç1‘.€¡èGö´þ˜ @¯ÇCe) çLÞ¡!|ãëÊ÷‘\<¤~K4#PO”Œš/GvQ¡2è@2Zù¹YmµŠ÷|po  ×Ã/ofggfg ÙQB!LÂô\‡Æ<‡„ææpÏ]Ák¯â–›°éiÙR0o$‘e±ÝÆ%—òŒ3yøQX·+Vè±GØ÷Lå´ŽÍ­[uôÑìöP­1 dÙô}–ËhÎ#Q*Óqñ£«P®°ÓÆÛÏÇ~û³Ûmc|Ê®X®ƒ7à±Ç˜¸.m›ç_ˆz۷˲Øjâècyæ™(W¸i“êµ´#ÇX½†kÖÀ²aO>ÁžÇÉ‚EJPd®gòlŽqçÎtµkš»w‰ˉæ¹ÎAÒn®ýbò¸Õë|÷ûØjÂë! ¸roº!!vÑ e¦}·„-›±{o: ¹8ƒí&ZM´[Øÿ=÷,ƒ =!£n‰+V$PÁbÏ“1û.r‹ŒmsǽðƒÇŸˆ·ž¾·Èq‹ž|ö’é«(› (*ðòHCÑÞWaŽn¼ž€\‡Æ1$SKž&Ú-\ô.|ˆºÖh4´z5:X¯¼b€e²'ÅÒk¯ð™g´b%w¼ÅKÙë 0· žÄ-᚟¢RIOì`§ƒjA ÄŸ@Ò¶qâIúåm´,þþG±p1Ž;cã¼åF­?˜ï~š-­^‹U«ùãª\!ÇÁÓOê´3P«aÑ~îóúÙÕ|fS²Ko@jë«üþ:ÿîšM 0ð†è´”“aó0 ’fË™*R©3ÞG«Ö¼bT©L±!ÍÏ)¨ýû‰ ]x1ý€ósa¯'¯Ç0-Æ1 ŽŒ¢Ý†¨8䪵øý¤¨¿ý¦wó¥lô#ÑÜ ¼¬ërzñœó6LïBá¾û”Ì•Ñ£ä †E5QmÔ]æŸG‚™QXÔ“ˆ¤Â€‡nþ¡ÆX±’‰>§/gIk’üOâq‡2FzfbŽWÞÕ"§„¬ÜºÖ—Z†Eذ6kuµš´lÖj˜Xˆ-[ öo¿9üõß¾eËP«kv†o9®ÓèVÊØ²×ÿ›_NC_öz(Káºh7á– XÓÓ¬VH¢\V½­&O>?ºŠ‡†™,XÈv Ë–£^c"Ôó|{\—s³ŠBD.N~ 6¿¬ngž‰ãN c ÀÜœž{†33°Ñ¢MÅC£cܺU%…KC¡½‡ªËøˆ,àßçEkx”í®¼##(ZkÒ‹DbßýðÑ?d«¥J_Ý’˜ÓHÇA¡ZIG;aüá©Ù¢ï! ð‰Oâþžaô‘§­àמ;tc¿º –-€cc0ðSRgtµMn¢öhêgé¯*@H:5Ïo½Æ|- nêS_÷X®«ž×Ϙò« YKÎ¥Ï2/Ý5R1œ0³l¨¿ñüÝ:¶¶måÒe Jª×97‹R9ÛóQ6C©Ö°{Z““,¹ºögéÆ?7·„J%-î=Âm·â]—¦ydÝž&&8¹Ë–áêRr~^®ËR7^Ñ1í˜â[OW$1jpܤm‚ÀÃ~û±ÓFàƒTàÓvP©páBôV:]Æ1Gбqtۜݭ(„ã€6Ž;[_C§c\úííþLÆ@eˆÉMÄW&·ë+ÿÂå+°}{"³e±YÞÿâ#­^ƒÝÓJØ'‰y(ðÓo6 T«ÓëazwšÁ¸Ï¾lµ¥ÏÇĶoÏëñ>œF'”…&x¿M”ð´³ä,ô×(Ôò‰“h °çJ&÷ ”²á+óVBvÑéè˜ã¸÷8ƒ›s(îDÙÁ–o=ÌBFÈr1šÍ8e”©À&!²0PËû›n™Ï<•«¨X¥2fw£RÅ¶× ­Y‘·*²QÅÁ‡òM‡ãþûxè¡8ìò}þêVÝs7z=XÒÂæÍzøa¬?A€Z•÷Ý-ËÂý÷aëVT*ô|ãrœqvï¯áaBš™f}QŒn[µ:=‚ê þâ6}ôèy´ˆZ Û¶áÕWpÙÿd"Øí¤œÆW©Ä•Œ"•\f¾ÐB*£L'Í.y¡bì«hhãõm ml–ó“åpËË:ù-l6xì§ (¹;.K.ž| o¼ž=vNÁ":=X„å är~>ïøçõ²XàùªTèu庌2óW.4€™òG- ZC·ÃX*¹ŒRÜ#Ú° …04ÍØèMœŸåÂEø?-"¯¿‰ŠØì¼Ê¼ ˆs{P­s\±d6ë”[°Ò‹SÌV‹Ž›U˜,®ôøs=ò{ÞöXäØ8¾÷]mÙBÛ6†`Fz ¡w\Àå+ุøRÅwî€À0ÀáG`í~üæå²˜!÷ù‹[uÏ])¸*±)ÒbB¶,E¯ú>–.Ó¥ïåºuŠ"†v¼¶Ãv;oZNMñtÚˆc¼¾×]ƒXª”éû<Œ“³ÂÏg4q–°¤Œ?lbXASqS¸ï!gçï>“ñ˜þ¿~Ú,@ʱ±e xÞ÷ö|=öÆÆ¸ï~œŸOeÏWÿ>ÊZ-5Ľ²E?ˆ£ŽA§£Fƒ¿ù5fgŠYæ$7oçIœº}êOi;˜ÚÁk®VJŽQ¡²—˜a€–:{,Ž}3,[–Å»îâý÷ªÞÈèüæã–Ý•©äú£tk™Ûff5=ôâ °ÿŠB¢T˜B#êæ”]cy˜è¯¾ãŠÀà5ÙH%­Z­³Îáì ¶lÁã"dY0:ýŠB.^‚µû Õ‰ýf¦Í-S™T®Ë‘QT*êõØëbdÓ»X©(躬U´l9¦v0+˜,‹ÝnzØ%‰#Ùe.ŠxÄQzÏ{Y®rçÅ1½:mÕjlµpïÝhõ„Ë… IDAT·ä8Ùɧ›nà5?…m D½‹)ŸÐrûéÇ/Á÷ø!;=_{3»Q©ºsèiŒ;¦hqÐI³ÛÁ|šrKt]”Jz}>ûi6êl6!`ÍZ´3»±í5ìJ±é§Z¯óæ›uß}8÷<þÓG£RN‰·y‚BÀªçéKÿƒž‡N[ËWà÷>ÄË¿†Z=¥«ÅQôÚm¾ëÝ:üp¶ÚHµN;ÏçŸ5áÅÊÈl‡çÛ† %…ŒèZ$2~ÇÀ‚ D¡º\MèÛD>–4Ê6 ¡<¨ W‘Ç‘ÞqO:YQ,·ÌcÉ'áòÿMÏ­TÅ<ä0½ã´9.Ãþ9<ù~ú£Ìr’mÙK²˜LaaÛœoB1z]D¡,‹ŽË+15Y܃dúHóÖ²xà:ú>D/ÄÖWT*ѲøÚ«¸â;P.¾Ïr)ÛIo¹IçœË(¤ã"Žä8Œ"m{S;°f_Œi÷nÞz3zˆõz?Ù8é !UAúˆü[VѰQ¸ ’êõxö9<î¸@ÌÏqûºò V**•¹k wüRaÙL:ÞuМÃw¿z=`‘0s-Ì~ ÃO@»•bÛâˆK—'z3µÞÜó·GZ»;œ=¶ ßKD8édmzЉ!IæªïqÛ‹¿Þ| ͇8‰…±jõÀ(æUt gçúWçþƒ%)»µG^ÿ÷õ[†·-õeä<*°v?¼y£<ŸŽË8B Žé=LlÉToàä·Â²àu¹sšsššÂÒ%8üˆ¼-››Á!½.žŽ¥’ l a·LÛa¹‚0Äö72K©Œ¨÷â]ŸùSR,>›sŒ#zz]­\¥#RèË ƒeÓ¹uº\ÂÃaÇ$¢Q$Z …$ú  Š#ýÑGyÙ—°éiTkPœÏY–¯ÉÉhS†R,9ysä·2NŸYCyÞz 6žZêõÐnstûÈþŠÖÌ(-–\:n2WH»D?Ô¬^K_ƒ øAt¢…ÉID!Ò°[##ìvÍ‚AFSÈ ãPaÝz„ÆÈ÷Ó'Õ²°`‚Žcð¥ÁÜ»‡±ÙbÊgÌ<Ž`è@÷¶y½¾ŠY{bú|Á>×(“1È,öóW¦l¾‘¼(â~OŸúÚ6«u4çÕœ—ïöÛK–€©d†Êe6çÑíɶpÐÒÂE}rNÙOoø¶£Ÿü¿¾=¦¹ÝhÎÃu‘„³÷º°,½¾URA°g‘h†C_û3¾²º4™o¿Ykð‹ùŽ ††¶?.a2 ®ƒ¯}MwÞ‰ÙNïâ“cnVc Ôë±\æùÁó†§d /Þ¬™)„MäSN -D^汊µßq~Ã-ÉuÐjñ¢K”\vóòU&B;Û ³4 ŒÛĹ™¡?-bëkܾµš@Ù¿ÿ=27Ί9TÓŒcstDí6¶¿‘˜Zá8¨V¡XžgšÈrÜEžE+.W²ó}¥×¾^o9íw–@>D,« K1bÌúÍõ¥™ÝØ0/ïmb‡0ä)§aÅJ$³R߇[b·£¨ËZCß‚þÊ%Ñ¢m©T†×"F‘ú½ÄínŽ›YHG#ÇàûF¸ë·8ól­Ý‡Ž£¡aö:úêWòLv‚)iË•éy |»­o^Î| & ÈvØœ‡m¡hŸ}èºLry¯&ï5§š¬J™<„Ç ßDze,—à8h !ôÍý°¦4€`Z¼-¿@ÊåÊÍ“a¨'²9ÏRqœ.øn›‰fá"VkèõŠ ÌlÚ3¨±)F¦äa#f:±$þð*ì¿?ÇÆ±õ5¼±¶•?6{àzrM¨ãðÉ'±~:íô¨ X6ž†åÊÁp˜é\”Vè8 º|¶G{ŠÈö8Þ|3sþ©oô†éÛgŸˆÁ´Ï+é7H,BiÅ x;-D‘’“ζIKŠ@`á„‚€°¨žÏv Q”œõ©Íq¥8oþ¬þ§b;p6p\v»°,^óüÕ_"Á\æŽkck0…ÝÙ,`¹¢|OÛ¶©ÓÁÔH°Œ³>d@r·1îèÿŸŽ“ªRJ%>ô€z=´Z˜|wÜŽjÅ•˜³{©O—Tn« Ÿx¦!)&p“®ëô´|qÄ(„Z‚ðÜ3š›…$ň³½Y…Ær.¤7œ Ù3+½rì-aYxñE/Áö7 †­Xhaj/x’§žÄ¶×åºÜ1‰À‡ïÀ-Ó ³Î÷p³³åjžÂ¹Tš ³oÌvôâ <ûlßžè\èu±`!æfðì³|}ŽßˆXh·°õ5Vkf9¤B;±PwËCÉp¬¥±,ÀÒÎ) ŽçŠ„¬¡!üàJ·ûìËRÏ=ƒ-›19™€æó2OùnR |ÝæóUÃ/Ö7O,LdØ¿kàáªï!ÿƒ l àË{Fz$Íx™B¾ AXryëÍ8î8Í·P®¨ÝD¥ÆRíææÕióÅçÑß6຺ægìtpá%šœ¤ENOã¶[ñÒ‹¬T ³£B%CÎÍá̳ÂóRš€KßÃ/} $XEc®p,cQ)Oé¬5HhÁn݆‘a…!mGýœƒÁšõ„aÊUsËR’EXÎ8[·ÿ‚?ŠÆPê•2܆`²&ûŽxã÷eZH«kiûáQ6^|wßuëGJ¢eâ;§02¢Gæ×¾¿ ÛEéÉÇyó²,£ºê—¤ÿéê(–4„9í2£, &rLRž˜$=°\Á£ð¡Ó½’T¹D£Â-t»òÓÀ<¬˜9(”eöõË•>Vðÿ\AB2/f4pͦ‘ðfÚ^iVþ’‰ƒÌu¡–…¿ÿo|v_|33œ›Ñô[s³¼ïMM!«¨<«×à¹gõ_?ÏvS¶ƒ%KpÚéX¾"k#äðùüpаd ÆÇÕj*ð`‘ÕšÖ죕kpÖÙ²ŒÒÉôŒ„¡Ù¤Í:/2/µ:®ú-å¢%zâqNíÈ\ †G9qш.ìëÆ-u»üÃOè#Óè(/ºDùyu:è‡Ïfò]#cHÙýM}4A\Ò/Mû ‰¾º,w6†ô‹[´};Êe&hÄáa@ü³OóÃbÁbr,~8ÞÀDa*õ¡,æÞ4} vú¯Äl݉ ÂvØíÊ÷ EBv7E!Õ4)Vl©;™ ²Š·åЇþç“ÕP2&éC8±°Ÿû;N€jM &"ƒYD{iî; ɺ@œÉˆ"Þx=l‹Ž‹}÷ǪUز™Û¶Áë2ñ’˜™Ñ{ÞÇu¡V€F­&"ib‚ú}ü·/°V5ëAC6oa~Ní64†5<Â8¦ïÂqqô±øòeHAð€EìžÑøî¿¿î¹›‹æ4›6×ÕgþŒÝ6ÚmpX€nn™Ñ$QQ¸™|ës³z×{°twL"ŽD‹å N;¿¹CŽ[îÒ} (»h{¢hbž-œ.Fß×þµªŽ;í6z=>ðŽ>Vköa»Å¹ùD>Êf ç½O<ŽÂ‘hæ3©(f0}s¾›ù1Z]¼û}X¼^z·Ü¢j…ˆ3—ˆŒ©ZFÅ*èò‹·² /¬ñó‹¼hІLÑÅÞœT{,€FƒK–br»L@¢ÀAêµáR-rQ`å_.ÿIluqÌçŸÁ¦§áذíÔ®.(ð±ñœôLOÃ÷X*K¤[R³ÉÐGcؼP4Ì~OÓqùø£:ä0 Ñ-in†q¬À'ÀZMçœÇ›oLäßþ ׄ¹Yž}ž®ø6[- :ÙûmàanËW¡1 ¯—øÇ÷:–Ñ—" ñŒŽ9–§žÏÓÐgf`Åèu±j5¢¸ÿ%ÐÄ}À´ÿõ¯=F«§Àf£ñ€Hi! ¢l·qÓ©þ< ±b%§&ÑëÂ"¢þË…ï©TÊîoý7'fÓC¾•«™´4q ØøüŸ«Ze# xø‘X·ÿë_/X‘VNÃZh¤ûJ…£Ž0G|Ê‘,éAA#­¢_ÅfãóÄÞá°7ñ?^ŽƒJÅ3)c0…ÏñY¨RÆÅÎT@ÅbÉV÷ËfÉ6z(©Ë›§ž®©) V!hÙPÌR Q Ça£¡(Êõ}‚áȃl›7ßÄÅK1<*;`cAÅèt…X¼HQ@QÄsߎ•«0½KQÌJ…眇+¯HLºæ:Oï<=¯¿ŽUkÑíÀ-qb!vL*ûör­ZjÖËø5içU1= 6hѲU«3 `;Úö8,ËŒ64™ꛊTðZÐxYh22“SÊR)f©$’Q„‹Þ¥äÐp.ØíHëCŠ"AzóÉ(qùî¯ü۰?§/>Œ±ÏZ{œÆÐëaóf-œ@»¿§0ıqœpîüm?×1¿ ɸa0/<¨B·1ç ä[‘=ÿâ{Š×ù8æÚ}ÿã6(ê ,Z’£/r8 n‹úÅ1©B7rõŠŒ ¦Bvw•ƘͷÔ_°`¥âAˆ(J¼Np\”ËŠ§ŸLÅÙdH0˜S{DŠÙë¡Ó†×£åhh±8:ž4yY®hÉ"4›ê¶|¬[ÅK‡f?7)ÎÓ?fdS“˜›U ŽÒvjÿ\V¶+FTÆB»­ÙYyæç1½Ž£(b!ŽUryÏÝH›³T6SH ÎÞiæ™FqYÐHfS|)?4Ó»ðÁãðÃY*ƒ„í¨RÁè8“€³«~€áќΕ'ÌæP*åmÛüž%Wo9û€z]µO;ƒ ”2Ž„Ôw»\½&ˆ-ÌX3÷s1|‘æÓò‚(Ö4¢g¿…æ‘& F!–­øO”@&œ×œ7Í–â ËÐF¬38&cŒ3FG«•+ùè£xèÕëú˘ŸW§Óç÷´ÐœG¡çññGtǰmãÀÏ7§¼eg[˜Úzí6|¶ Ä,¹²‡ðÔHœS‡ù¦††Y®)¡ÓµZxíSyWaÄ…‹¸v-ü¿ú%N=]ŽùyMïÎh–FgÞJ3ÞÎ< ûî…xñ%Üù•\4Ûð=ù>[MÞplÛ˜ÍA¨jsC˜y+a&¯Ì¹ ƒÑ ÅÆ á<ç<­_Ç ‚ï«9O· × ±qÜr37=²^0 lßËh¬`I^A©D×ç# “X1Mí@¤³j Q¨™:6M‚Då™`$³­Î¢*‡Ìýh$÷Ø. ©é¿c33&ôw.€cŽ×=wѱ /žÌüHã¼RŸá—wP î5æ {ý±wÈ}D‹3бj 8W~—ÃÃùï.—xåwñÉ?A· Û¦ecl$œ®ÊU&Èæþñ=ƒhÓÙLàA1l'É=€[bk7n»õzê¼ç.|òOXTÇèg?áHtŸaÉ–,Á‡?ªj‡Ù>õ$¸AÀ8VÑ‹TÌ‹ã¼wਣEð¬^­|ˆÿüeE»=Ä1\7…GÀ0+¶70hÖ‹á1…4-, ‹rf·šsh·°f ׬Q$<’äb€¹9Üt¢Nòô[rKð}y¤.¹QœG3Ø\bYxíULM) ™¬T0<ÏÓM7ÀqúÀF ¯¿ŽÏÿ¶mÕ䤮ù }´0QIfjo>^QÄÀc»Í‘Qq$}?ïJm{DCr]lØ€RósèuFôzúƒaùJ-[†£ŽQbAL ¢ C d¿Üè)g±©fDOÚ¥!  A'r žÏV £žŸ@é (ÑJä{ Ð9,0†þ޾ûmÌÍÀ¶ñòËüÜgá÷D¦2;›üù5°ú}\d3øTk4 ˜“ %2e@½ûŽBWælb¸g‡* A}çÅ{]{;Ž8½Ý’‘.©fŸ1y)Ô:æÜAy÷Àh’yžü0u9”Ê$tÖ¹Ü5…gžÁ+[ö7=¦_ÀÛÞ¡ #ôÛl6•˜Ö\‡ñ1ÌÌ¢!y× QÈqùã«ðÞÂ÷гU«bç_x>ÇþŠé‰ÿïÿ–BËúDÁ sƒ8ÂÒ¥Œct:CHHÜ´4#¹=È0íÆ`½ŠzC3;ÓÈŒ°£ZK–á#C¥‚v g­ûîæm·±^ yqþ¡«0jƒYâ°8{ˆÁÍ}LÌÅ‚6¿¬ƒ7Т•ªÕôÓ~þ9ÄçÕÎ ÃØQ‰Wñ¯'î •Ëüö·tÔ1cbÓ¦4ü3‡+˜Ý[S2 Ά"5ÉÄðÈ –çœ"Bmæw 8Ââ%ÿé \Ñ쌬ü UÁ÷ž]“Ì´`3«'Côjà2“ðÁùØ#é—W©¨TÆêÕ8âh¼ïØÿ€þ!&¹gfØíb÷.ÍÏ%ì>y=øžö[§(ê‹yÌ’ò«¶ã൭º÷nètùƒïóË—I2:ÅýaZ©ŒrUýö\ÎÖ踺ÿ>Ä‘H•JC현cç"S\šGY0I´…bú!,[ ·ÞP¨\ç£Ý†×Ãñ'jíZÅñ€¿y/g@vÐ<ôò‘^F’3E’†1Œ*—qýuAD¥¬Ñ1¸%Ù–,æ!‡*޳<ÑÅ( ̾”BµŠr • Iu:øí¯qíÏtýuÚ²9#ÂôpeOE¥cô½2Õsèsv/7춦%;T€U4çqéûÿÓ àÆ“8?§Ý»äy©¹)ÁÀˆ‹,\˜É‚`©¿:ó//VtýuxâqlÛÊ0`à3ŽÇ½óBÍÎVúª«UR¹£²Ìâþ¨9­Q2.~z‚D!¢0Ó’1±ÝYÌEÖ,ÔML1À‘¢‹cÅ 4†ÐéäÐ\"÷Ò.æõ¦xÛ˜ÈZâ¾Ïv[Ó»¨xñ;K _ývM‘nø¶læ/nF»©‹èº*—“Њ¬Õ1ÈÊ2ô¤Š–¶Dýgá–›pà:¬Z¥ $¥´mŽõ¹È}%Ì®iLM©^ãÈ8‡‡ÑjA±6làãÁq2˜ I¬$”Ë<ÿBìØJ…qŒRY\ˆ_d·ÇdÊb5ƒ¼?ÍTAþ“«^¥SBsaˆ~œ}¾í¡È$ÇâϯÁgꤓY­kûvþäGxîYüãÿ@s¶€ã ôÊXæÐ—2Í×c6Éšk¹5¸8Ê5c}’n}¨ý*?ñÇ(—Õë1  qÌzCyWÔ×r@óÛÍû@QÛÑAë O?ÍJY2•‡æ±@õÅjïÿ jU:.ZMm~™·ÞÇæ¯`À—ïúáîTÀ÷Ñíb÷NtˆŽ?‰‡Æ7‰RiÐlñ,€F#UM|ò3ù±ð›_áµWðËÛ°ã –KŠcöºð}Ø–hѲ°ÎQr–;•ÇÆ¸t©ÊUÆH°•d‘cbA25D)â¿]É ¥2ZMÄ‘š-n8$•3Ðô"ø¤áaf—¿¥Ë•ŒÒ.¾DW|¶ÅTb¢LôU´àöM-y9F»µµ ;›ÂôAmÅ 7×åÍ7ñÆ`[Œ•R®ý7žÇ¡ëê‡Wqv6A${þ. †Wõå–êåòá˜9á—™1VÍgr%V*ºû·xÏûSutqxTaÀ¸²á€[Å É“¬ú¡!}ìã¬×!aáíºãv¦¯‚‰'=’”Ql/Ôygrñbú¢å ׄGáîÝ&¤¹+)B1$D!À$J•–%ßã±Çã¨cqØá8ð ½+þ³ `¯?o9 ?ð˜ÞÅ™Ýx}wMazŸ;¶ã©'ÐnatTn)ej'ï¶ŸP™~_®Ë~ c  CÚŸ£¨zƒ/¾ˆ¹YÔÈZT«Åø".û²Ú-ãHn‰óófAlc¨VZ-´mÔê°tÚò}®Ý—Ç0AÉŒV~˜Â°Ó™“÷\Bš‰= ŠƒÀ>•²ÌŒZ@>À—^ÔÂEœÞÅ©©TðXŒŠßþkPH BT„PijÚM± î/Çá /`f7l]q̧žTà3ã´šs{åà#e046Îá$ƳÎá¿5ïõÆ­ÞàkŠcáÈ£à”МdÊ pzZ$hÉ"¢¾Ç8D«NËWbÃ!X0ÁÃŽ„í`ÕŒcÕšÄïñÿôÇÁÿ»ŸX0ý Ç ñë_ñ¹Mxú)Üó>FÆR_ˆe¥ßßòå¸k'KeÔªÉ]SøÎ704¬(ÎCh!Ú¶l›W^Áw^¨(ÄØ8ÿî¿`x¸ˆ›0¢3I´Ûºÿ^œy6,›­yŒŒ2ŠÑiaÝA¸ãv AÊÁv òCÐíâ·¿I⺔3Á[1{¢©‹¼>åaFx•9ÞM’ 87§d#0e•,¤pÀ†•u_ 3¸…(bf@ƒ@Ã¥RR¿Á¶ñͯãã¬á!”J¸ç.\óS&$<\Ze)Y™j§@gËOž8æð0Ú­'Šío ÛE£‘ÇÆ£2š9y$,Zˆ ÀÜ|ÊŠ©T`Yœ›U#qÌÏaÙrœy.V­ÕÆ“¸ÿEåÿ×îwúÿóÏË/`ûvl{ Ï> Ï×ü\‡g#¯Ç(Tc¸ßOK%\y…¶l¦9!ŠB àøãtØ‘tÜr“~ˆ®kRõ³(…þi¡Õäa‡é÷>ÊZa²å,‹wüR7\—Ðoà{8`>ñ)zBŸSSúïÿ€ÆP?Ã6Õ3©Óá>û`tL³3ܺ Ž=°·ùy‡dP¤ð·wu!R•aøyÎ9sÎìÎ츳þàú¿.Ù–BVbÝ•ô#atS7FBÝ]ÞuQTt]E ˆH•ýP’$R¸Úº¿îìüœ¿ï{»8gf¾3ZÐ…¢ØË¹žøÎ÷òÎó>?­DE°Ì ŽIŒï &ÿ" i»85?5ŠpϽ²};ݼ\¸À3§11LjT*J…JK¡@Ѧ$¨#ûG:$]-2¹Ä{X.KóãКÿ§ÛíC)QŠ¢%VœüKÞ~ NË¡X¢Vøù4FÖbé6Œ¢\¾¡¯ç¿†hÔ‘Ï#ŠÒ)ãê<''†˜šÄb‡IµF×M¼LÄuùâ~Y±Š•«I ½'³sí ¸m¬oò˜ ¼öºä»¡"Šˆí°ZÛâá÷17 Zˆ"yãmGu¨^ŸŸÀÉo÷ét ò}îy [· ÉÙiœ?/'Ž«GƒäšÕ̶…÷Eà8ðò€²axY¤Xp ã¶uwÚ6$—¦+M¦;×kØÿ² /§åHРe¡V•O?ÁÄD¦s˜[Dà *]ÑÁŒL¥m›4¦X‘0@Ѳàæ+ÑŠͰ~#Æ·²¯7á®q ÀËÃv`ÑÌn¹9åÜäïƒë¦+'/Ÿ¾°…¢\ŒgžÇéeâ"§§äì–zÄÍqj]Ýð4—ᡇÅËóò%|õ¥„aÓߤP´SÛº&ó ˆ%È®~˜P ;A(;wad-ƒWgá¸Hüv›oÉÌZËf'‹ìjÍØí‹’Äœ¥´v¥Å²06Æbœý…9…ˇ0;/Ó3Ø0ÊÞ^lÚõÄ­Unµ²mnÛŽmÛÑa:Ù¨C4âŽÃƒo¦ÛûßÃÌ4|ÎÏÉäeL]A½–îòÖ­co±‚Rô}QJ¼< ™ŸOw]®‡cG¹ûq©T(ŠåAù¢…]4ßëB@¡««c é¤ëþyÁà2ì{ QD‹24ÌÑÍ|ç­¤G¦fÒq g,#ݰ­~4vRõQKÂÒ IÏãØTE)ÂB‚–DGÖH±‡AÐb¬7 Ñ$ªAC½ÖT¢ÅÒ¨3±¬Z²CËeÙ‹Ez8¼CÃ,÷aËÝȹ ÔjX½†FZÙ­\n—2åÌOî½Î0g’=ËÕ«q風ü:ê5º®âØQžþ ýýð<±žüZêu>𠺻åàA0W®„IDAT+¯'ZÑ÷åûoqîµB!Їc‰#Ä1ã:†Ò"’¾^{ŸÆèfñ)¬ÓÕ-?|Ç#G$Ÿ¿NÀ\Öz£Å+i[ß%~!‰Ÿ³e‰í0ÉÆsrÈås‘ˉãÐv$ܴ£adM*0#‚°>N’þ~”zY*ÁË‹ç±TÂÒ”ûpçÕxþCi•ÒàQ„F– ÑÐæ£R?3ÑM×!€ž\7ãøX\LC:”‚Vi+·,Øv›P‡>²ýX–ñØ©)§e¥P¦mV’±ùÿ1þKý ^:‘ÜÆ›IEND®B`‚PsimagLite-3.06/doc/honeycomb.tex000066400000000000000000000035271446452427400167750ustar00rootroot00000000000000\documentclass{standalone} %\usepackage{fontspec} \usepackage[T1]{fontenc} \usepackage{tikz} \usetikzlibrary{calc} \usepackage{calligra} \definecolor{myred}{HTML}{ff4136} %\definecolor{myorange}{HTML}{ff851b} \definecolor{mypurple}{HTML}{b10dc9} \definecolor{myolive}{HTML}{3d9970} \def\a{1.8} \def\c{.86602540378443864676} \def\s{.5} \begin{document} \newcounter{mycounter}; \setcounter{mycounter}{0} \begin{tikzpicture}[ ystyle/.style={myred, thick}, zstyle/.style={mypurple, thick}, xstyle/.style={myolive, thick}, nstyle/.style={circle, draw=black, thick}] \foreach \x in {0,...,4} { \def\y{4*\x} \node[nstyle] (0\x) at (2*\a*\c*\x,0) {\themycounter}; \stepcounter{mycounter} \node[nstyle] (1\x) at (2*\a*\c*\x-\a*\c, -\a*\s) {\themycounter}; \stepcounter{mycounter} \node[nstyle] (2\x) at (2*\a*\c*\x-\a*\c, -\a-\a*\s) {\themycounter}; \stepcounter{mycounter} \node[nstyle] (3\x) at (2*\a*\c*\x, -\a-2*\a*\s) {\themycounter}; \stepcounter{mycounter} \node[nstyle] (4\x) at (2*\a*\c*\x, -2*\a-2*\a*\s) {\themycounter}; \stepcounter{mycounter} \node[nstyle] (5\x) at (2*\a*\c*\x-\a*\c, -2*\a-3*\a*\s) {\themycounter}; \stepcounter{mycounter} \node[nstyle] (6\x) at (2*\a*\c*\x-\a*\c, -3*\a-3*\a*\s) {\themycounter}; \stepcounter{mycounter} \node[nstyle] (7\x) at (2*\a*\c*\x, -3*\a-4*\a*\s) {\themycounter}; \stepcounter{mycounter} \draw[ystyle] (0\x) -- (1\x); \draw[zstyle] (1\x) -- (2\x); \draw[xstyle] (2\x) -- (3\x); \draw[zstyle] (3\x) -- (4\x); \draw[ystyle] (4\x) -- (5\x); \draw[zstyle] (5\x) -- (6\x); \draw[xstyle] (6\x) -- (7\x); } \foreach \x in {1,...,4} { \pgfmathtruncatemacro{\xminusone}{\x - 1} \draw[xstyle] (0\xminusone) -- (1\x); \draw[ystyle] (2\x) -- (3\xminusone); \draw[xstyle] (5\x) -- (4\xminusone); \draw[ystyle] (6\x) -- (7\xminusone); } \end{tikzpicture} \end{document} PsimagLite-3.06/doc/manual.bbl000066400000000000000000000000001446452427400162050ustar00rootroot00000000000000PsimagLite-3.06/doc/manual.ptex000066400000000000000000000217351446452427400164500ustar00rootroot00000000000000\documentclass{book} \usepackage[utf8]{inputenc} \usepackage[T1]{fontenc} \usepackage[english]{babel} \usepackage{xcolor} \usepackage{listings} \usepackage{graphicx} \usepackage{fancyvrb} %keep \usepackage{fancyhdr} \usepackage{booktabs} %keep \usepackage{mathtools} %keep \usepackage{hyperref} \definecolor{mygray}{HTML}{AAAAAA} \newcommand{\code}[1]{{\ttfamily #1}} \fancyhead{} \fancyhead[LE]{\leftmark} \fancyhead[RO]{\rightmark} \cfoot{} \rfoot{\thepage} %exit \hypersetup{colorlinks=true} \newcommand{\cppFile}[1]{\texttt{#1}} \newcommand{\inputItem}[1]{\noindent\texttt{\bf #1} ---} \newcommand{\inputSubItem}[1]{\indent\texttt{\it #1} --} %% Remove the below command before submission \newcommand{\todo}[1]{\textcolor{red}{#1}} %Format to denote a C++ class name: \newcommand{\cppClass}[1]{{\sffamily #1}} %Format to denote a C++ variable: \newcommand{\cppFunction}[1]{{\tt #1}} % for the cover page: \newcommand{\HRule}{\noindent\rule{\linewidth}{1.5pt}} \newcommand{\ptexPaste}[1]{\fbox{\textcolor{red}{PLEASE RUN ptex.pl on this .ptex source to obtain the correct test for tag #1}}} \newcommand{\ptexLabel}[1]{\ptexPaste{#1}} \newcommand{\ptexInterface}[1]{\ptexPaste{#1}} \newcommand{\ptexReadFile}[1]{\ptexPaste{#1}} \newcommand{\ptexReadFileVerbatim}[1]{\ptexPaste{#1}} \hyphenation{Wave-Function-Transformation} \lstset{language=c++,basicstyle=\footnotesize\ttfamily, keywordstyle=\color{blue}\bfseries,frame=shadowbox} \pagestyle{fancy} \begin{document} \begin{titlepage} \vspace*{\stretch{1}} \HRule \begin{flushright} \LARGE PsimagLite v2 Manual\\ \end{flushright} \HRule \vspace*{\stretch{2}} % \begin{center} \Large Manual Version: \today\\ \end{center} \begin{center} \textsc{Oak Ridge, 2018} \end{center} \end{titlepage} % \begin{titlepage} \noindent \begin{minipage}{0.4\textwidth} \begin{flushleft} Gonzalo \textsc{Alvarez}\\ Nanomaterials Theory Institute\\ Oak Ridge National Laboratory\\[0.2cm] Oak Ridge, TN 37831\\ \today \end{flushleft} \end{minipage} \vspace*{\stretch{2}} \noindent %\begin{minipage}{0.6\textwidth} \begin{tiny} \fontshape{sc}\selectfont %\begin{verbatim} \noindent DISCLAIMER\\[0.2cm] THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.\\[1cm] \fontshape{\shapedefault}\selectfont %\end{verbatim} \end{tiny} %\end{minipage} \noindent \begin{minipage}{0.4\textwidth} Copyright \copyright 2009-2018,\\ UT-Battelle, LLC\\ All rights reserved \end{minipage} \hfill \begin{minipage}{0.4\textwidth} \begin{flushright} \includegraphics[width=3cm]{PsimagLiteLogo.png} \end{flushright} \end{minipage} \end{titlepage} \tableofcontents \pagebreak \ptexReadFile{../README.md} \chapter{IoNg}\label{sec:iong} \subsection{Overview} \code{IoNg} is the next generation (ng) input and output (io) subsystem for \textsc{DMRG++} and related scientific applications. To output data to a file the client program first includes the \code{IoNg.h} header and then creates an object of class \code{IoNg::Out io;} with argument the filename to be written to. Next, the client code calls \code{io.write(object, label);} where \code{object} is the object to be written with label \code{label}. To input data from a file the client program first includes the \code{IoNg.h} header and then creates an object of class \code{IoNg::In io;} with argument the filename to be read from. Next, the client code calls \code{io.read(object, label);} where \code{object} is the object to be read with label \code{label}. If an object's constructor accepts an \code{IoNg::In} argument the object can be constructed from data on the file. The classes \code{IoNg::In} and \code{IoNg::Out} should be passed to functions as \emph{non-const} references. The copy constructor, assignment operator, and default constructor shall not be available for either \code{IoNg::In} or \code{IoNg::Out}. \subsection{How data is stored on disk} The data on disk can be either a group (implemented as an HDF5 group) semantically equivalent to a directory, or a dataset (implemented as an HDF5 dataset) semantically equivalent to a file. The following types are written as a single dataset: Native types, complex of native types, std::vector of native types, std::vector of complex types, \code{std::pair} if both \code{T1} and \code{T2} are either native types or complex of native types. All other types involve the creation of one or more groups. Moreover, \code{IoNg} will add the root group $/Def$, but client source code must not use it. For example, client code can write a \code{std::vector} \code{myvector} with \code{io.write(myvector,} \code{``myvector'');} and read it back with \code{io.read} \code{(myvector,} \code{``myvector'');}. The HDF5 file will contain \code{myvector} in the dataset \code{/Def} \code{/myvector,} but the client code should not use the \code{/Def} group prefix when reading back with the \code{IoNg} class. Only when using third-party tools should the \code{/Def} group prefix be added. \subsection{Labels of datasets and groups} Labels for dataset and groups must be of the form $/label_0/label_1/.../label_{n-1}$. where each $label_i$ is of the form $[a-zA-Z0-9-\_]+$. \subsection{API Reference} TBW. This will be pulled directly form the source code. \section{IoNgSerializer} \subsection{Overview} A client call to \code{io.write(label, object);} executes differently depending on the object type. For source code purposes two kinds of types need to be considered: \emph{root-undelegated} types, and \emph{root-delegated} types; the latter types are either native types or STL types. All other types that need serialization are considered \emph{root-delegated}. STL containers of \emph{root-delegated} types are themselves \emph{root-undelegated}: For example \code{std::vector} is \emph{root-undelegated} even if \code{A} is \emph{root-delegated}. \subsection{Root-undelegated Types} \ptexPaste{IsRootUnDelegated} \subsubsection{Serialization of std::vector} A single dataset is also used for \code{std::vector} if \code{T} is native or the complex of a native. If T is neither native nor the std::complex of a native, then \code{IoNg} creates a group with \code{label}, and inside that group creates a dataset named \code{Size} containing the size of the vector. \code{IoNg} then runs a loop over \code{index} and delegates the writing. If \code{T} is a root-undelegated type then \code{write(label + ``/''} \code{ + ttos(index),} \code{ data[index]);} is used, and if \code{T} is root-delegated then \code{data[index].write(} \code{ioNgSerializer\_,} \code{ label + ``/''} \code{ + ttos(index))} is used instead, where \code{data} is the underlying \code{std::vector}. Moreover, for \code{std::vector} \code{} with T root-delegated, the variant \code{data[index]} \code{->write} \code{(ioNgSerializer\_, } \code{label +} \code{``/'' + ttos(index))} is used. \subsubsection{Serialization of std::string} TBW \subsubsection{Serialization of std::pair} TBW \subsubsection{Serialization of std::stack} TBW \subsubsection{Serialization of std::map} TBW \subsection{Root-delegated Types} A type is root-delegated if it is not root-undelegated. Root-delegateds must include the \code{IoSerializer.h} class but should not include \code{IoNg.h} unless needed. Root-delegateds must have a function named \code{serialize} returning \code{void} and taking two arguments: the serializer object \code{ioSerializer} by \emph{non-const} reference, and string \code{label}. In their \code{write} function, root-delegateds must first create a group called label by calling \code{io.createGroup} \code{(label),} and should then go over their data members, and for each call either \code{ioSerializer.} \code{write(dataMember,} \code{label +} \code{"/" + name);} if \code{dataMember} is a root-undelegated type or \code{dataMember.} \code{write(} \code{ioSerializer, } \code{label +} \code{"/" + names)} if \code{dataMember} is a root-delegated type, with the name being the name of the \code{dataMember} in question. \section*{LICENSE} \begin{verbatim} \ptexReadFile{../LICENSE} \end{verbatim} %\bibliographystyle{plain} %\bibliography{thesis} \end{document} PsimagLite-3.06/doc/tutorial.ptex000066400000000000000000000125051446452427400170310ustar00rootroot00000000000000\documentclass{article} \usepackage[utf8]{inputenc} \usepackage[T1]{fontenc} \usepackage[english]{babel} \usepackage{xcolor} \usepackage{listings} \usepackage{graphicx} \usepackage{fancyvrb} %keep \usepackage{fancyhdr} \usepackage{booktabs} %keep \usepackage{mathtools} %keep \usepackage{hyperref} \definecolor{mygray}{HTML}{AAAAAA} \newcommand{\code}[1]{{\ttfamily #1}} \fancyhead{} \fancyhead[L]{\leftmark} \fancyhead[R]{\rightmark} \cfoot{} \rfoot{\thepage} %exit \hypersetup{colorlinks=true} \newcommand{\cppFile}[1]{\texttt{#1}} %% Remove the below command before submission \newcommand{\todo}[1]{\textcolor{red}{#1}} %Format to denote a C++ class name: \newcommand{\cppClass}[1]{{\sffamily #1}} %Format to denote a C++ variable: \newcommand{\cppFunction}[1]{{\tt #1}} % for the cover page: \newcommand{\HRule}{\noindent\rule{\linewidth}{1.5pt}} \newcommand{\ptexPaste}[1]{\fbox{\textcolor{red}{PLEASE RUN ptex.pl on this .ptex source to obtain the correct test for tag #1}}} \newcommand{\ptexLabel}[1]{\ptexPaste{#1}} \newcommand{\ptexInterface}[1]{\ptexPaste{#1}} \newcommand{\ptexReadFile}[1]{\ptexPaste{#1}} \newcommand{\ptexReadFileVerbatim}[1]{\ptexPaste{#1}} \hyphenation{Wave-Function-Transformation} \lstset{language=c++,basicstyle=\footnotesize\ttfamily, keywordstyle=\color{blue}\bfseries,frame=shadowbox} \pagestyle{fancy} \begin{document} \begin{titlepage} \vspace*{\stretch{1}} \HRule \begin{flushright} \LARGE PsimagLite v2 Tutorial\\ \end{flushright} \HRule \vspace*{\stretch{2}} % \begin{center} %\Large Tutorial Version: \today\\ \end{center} \begin{center} \textsc{Oak Ridge, 2020} \end{center} \end{titlepage} % \section*{Introduction} Why should you read this tutorial? The motivation for this tutorial is that you can use PsimagLite in your own C++ programs. Another reason to read this tutorial is to learn C++. We will pose exercises from beginner to intermediate to advanced. Moreover, some of the exercises will ask you to add or modify or improve functionality in PsimagLite itself, and so your solutions could be included in PsimagLite. You are encouraged to git clone PsimagLite and make changes that you think are suitable, and request pulls, and discuss in our mailing list. All corrections are welcomed, and either git pull request or emails are OK. The actual topics to be discussed will become clear once we have some lessons typed in. The actual .cpp programs that use and illustrate how to use PsimagLite are going to be in \cppFile{drivers/}. We'll try to make them fit in one page including error testing, and additional pages of documentation in line. The documentation inside the .cpp file will then be split in parts, and each part will look like the following. \begin{tt} \begin{verbatim} /* PSIDOC PartName standard latex markup here */ \end{verbatim} \end{tt} Note that the \texttt{PartName} will be something descriptive of what we are talking about there and must be \emph{unique}. Moreover, that part can be included in this document, the \cppFile{tutorial.ptex} file, by using the command \texttt{$\backslash$ptexPaste} \texttt{\{PartName\}}, where you have to use the right name for \texttt{PartName}. This way we import documentation from each .cpp file into this ptex file. In addition to being short, the .cpp files for the tutorial should include compilation instructions without any \texttt{Makefile}, so that all includes and library paths and compiler switches are visible in the command line. Dependencies must be kept minimal; you'll need PsimagLite, of course, and a C++ compiler, but other than that, we should really really try not to have dependencies unless really needed. What's an acceptable dependency? If we are showing how to read an Ainur input then we need BOOST, but should still compile without BOOST and run plain old data (POD) input files. If we are showing how to integrate a function, then we need the GSL, but again the example should be able to compile without it; it won't run though, but display a message saying that the GSL is needed. \ptexPaste{InputNg_Intro} \ptexPaste{InputNg_main1} \ptexPaste{InputNg_Recap} \subsection*{Exercises} We'll use stars * next to the exercise to mark the most difficult ones. The ones marked with M may lead to mainstream inclusion. 1 In the tutorial, we printed the value of the scalar. Do the same for the vector and the string. 2 Read a matrix from the input file. Use PsimagLite::Matrix for the type, and use $mymatrix=[[1,2],[3,4]];$ in the input file. Print the matrix observing that PsimagLite::Matrix has operator \verb!< Makefile.dep .PHONY: clean clean: Makefile.dep rm -f core* *.o *.dep *.a integrator sparseSolverTest testCRSMatrix combineContinuedFraction continuedFractionCollection range kernelPolynomial linearPrediction options randomTest svd testLapack threads loadImbalance testIsClass sumDecomposition calculator closuresTest base64test checkRunId testLanczos include Makefile.dep PsimagLite-3.06/drivers/TestMemResolv1.h000066400000000000000000000030421446452427400201740ustar00rootroot00000000000000#ifndef TEST_MEM_RESOLV_1_H #define TEST_MEM_RESOLV_1_H #include "IsClass.h" #include "MemResolv.h" #include #include typedef PsimagLite::MemResolv MemResolv; template class TestMemResolv1 { static const bool IS_CLASS = PsimagLite::IsClass::value; typedef std::vector VectorType; typedef PsimagLite::ResolveFinalOrNot ResolveFinalOrNotType; typedef TestMemResolv1 ThisType; public: TestMemResolv1(int size) : size_(size) , data_(size) { } void setTo(T x) { for (SizeType i = 0; i < data_.size(); ++i) data_[i] = x; } const T& get(int i) const { return data_[i]; } SizeType memResolv(MemResolv& vmptr, SizeType = 0, PsimagLite::String msg = "") const { PsimagLite::String str = msg; msg += "TestMemResolv1 "; const char* start = (const char*)&size_; const char* end = (const char*)&data_; SizeType total = vmptr.memResolv(&size_, end - start, str + "size"); total += vmptr.memResolv(&data_, size_, str + "size"); return total; } template friend std::ostream& operator<<(std::ostream& os, const TestMemResolv1& mt); private: TestMemResolv1(const TestMemResolv1& other); const TestMemResolv1& operator=(const TestMemResolv1& other); int size_; VectorType data_; }; template std::ostream& operator<<(std::ostream& os, const TestMemResolv1& mt) { os << "TestMemResolv1 size= " << mt.size_ << "\n"; for (SizeType i = 0; i < mt.size_; ++i) os << mt.data_[i] << " "; os << "\n"; return os; } #endif PsimagLite-3.06/drivers/affinityTest.cpp000066400000000000000000000036431446452427400203550ustar00rootroot00000000000000/* Copyright (c) 2009-2017, UT-Battelle, LLC All rights reserved [PsimagLite, Version 1.] ********************************************************* THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. Please see full open source license included in file LICENSE. ********************************************************* */ #include "Concurrency.h" #include #include #define USE_PTHREADS_OR_NOT_NG #include "Parallelizer.h" class MyHelper { typedef PsimagLite::Concurrency ConcurrencyType; typedef PsimagLite::Vector::Type VectorSizeType; public: MyHelper(SizeType ntasks, SizeType nthreads) : ntasks_(ntasks) , x_(nthreads, 0) { } SizeType tasks() const { return ntasks_; } int result() const { return x_[0]; } void doTask(SizeType taskNumber, SizeType threadNum) { x_[threadNum] += taskNumber; } void sync() { for (SizeType i = 1; i < x_.size(); ++i) x_[0] += x_[i]; } private: SizeType ntasks_; VectorSizeType x_; }; // class MyHelper int main(int argc, char* argv[]) { typedef PsimagLite::Concurrency ConcurrencyType; if (argc != 3) { std::cout << "USAGE: " << argv[0] << " nthreads ntasks\n"; return 1; } SizeType nthreads = atoi(argv[1]); SizeType ntasks = atoi(argv[2]); ConcurrencyType concurrency(&argc, &argv, nthreads); typedef MyHelper HelperType; typedef PsimagLite::Parallelizer ParallelizerType; PsimagLite::CodeSectionParams csp(nthreads, 1, true, 0); ParallelizerType threadObject(csp); HelperType helper(ntasks, nthreads); std::cout << "Using " << threadObject.name(); std::cout << " with " << nthreads << " threads.\n"; threadObject.loopCreate(helper); helper.sync(); std::cout << "Sum of all tasks= " << helper.result() << "\n"; } PsimagLite-3.06/drivers/akimaSpline.cpp000066400000000000000000000033351446452427400201370ustar00rootroot00000000000000// BEGIN LICENSE BLOCK /* Copyright (c) 2009 , UT-Battelle, LLC All rights reserved [PsimagLite, Version 1.0.0] ********************************************************* THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. Please see full open source license included in file LICENSE. ********************************************************* */ // END LICENSE BLOCK #include "AkimaSpline.h" #include "Vector.h" #include #include #include #include typedef double FieldType; typedef typename Vector::Type VectorType; typedef AkimaSpline AkimaSplineType; typedef AkimaSplineType::IntervalType IntervalType; void readTwoColumnData(const String& file, VectorType& v0, VectorType& v1) { std::ifstream fin(file.c_str()); if (!fin || !fin.good() || fin.bad()) throw RuntimeError("Cannot open file\n"); while (!fin.eof()) { String s; fin >> s; if (s[0] == '#') continue; FieldType x = std::atof(s.c_str()); SizeType size = v0.size(); if (size > 1 && x < v0[size - 1]) break; v0.push_back(x); fin >> s; if (s[0] == '#') continue; v1.push_back(atof(s.c_str())); } fin.close(); } int main(int argc, char* argv[]) { VectorType x, s; readTwoColumnData(argv[1], x, s); AkimaSplineType akimaSpline(x, s); FieldType xstart = std::atof(argv[2]); FieldType xend = std::atof(argv[3]); SizeType total = std::atoi(argv[4]); FieldType xstep = (xend - xstart) / total; for (FieldType x = xstart; x < xend; x += xstep) { std::cout << x << " " << akimaSpline(x) << "\n"; } } PsimagLite-3.06/drivers/base64test.cpp000066400000000000000000000033341446452427400176650ustar00rootroot00000000000000/* ***** ***** ATTENTION: This code has been modified from the original ***** and adapted for use in PsimagLite ***** Original notice is below ------------------------- begin original notice ------------------------------- Copyright (C) 2004-2008 René Nyffenegger This source code is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this source code must not be misrepresented; you must not claim that you wrote the original source code. If you use this source code in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original source code. 3. This notice may not be removed or altered from any source distribution. René Nyffenegger rene.nyffenegger@adp-gmbh.ch ------------------------- end original notice ------------------------------- ***** Original notice is above ***** ATTENTION: This code has been modified from the original ***** */ #include "PsiBase64.h" #include int main() { const PsimagLite::String s = "ADP GmbH\nAnalyse Design & Programmierung" "\nGesellschaft mit beschränkter Haftung"; PsimagLite::PsiBase64::Encode base64encode(s); PsimagLite::String encoded = base64encode(); std::cout << "encoded: " << encoded << "\n"; std::cout << "decoded: " << PsimagLite::PsiBase64::Decode(encoded)() << "\n"; } PsimagLite-3.06/drivers/binaryIoTest.cpp000066400000000000000000000017551446452427400203220ustar00rootroot00000000000000#include "IoBinary.h" #include "Vector.h" void readMe(const String& myfile) { PsimagLite::IoBinary::In fin(myfile); typename Vector::Type v; fin.read(v, "MyVector"); std::cout << "MyVector\n"; std::cout << v; std::cout << "------------------\n"; PsimagLite::Matrix m; fin.read(m, "MyMatrix"); std::cout << "MyMatrix"; std::cout << m; std::cout << "------------------\n"; } int main() { SizeType rank = 0; String myfile = "myfile.txt"; PsimagLite::IoBinary::Out fout(myfile, rank); String s = "Hello World!"; fout.print(s); typename Vector::Type m(10); srand48(3490201); for (SizeType i = 0; i < m.size(); i++) m[i] = drand48(); fout.printVector(m, "MyVector"); std::cout << "MyVector\n"; std::cout << m; std::cout << "------------------\n"; PsimagLite::Matrix a(10, 20); for (SizeType i = 0; i < a.n_row(); i++) for (SizeType j = 0; j < a.n_col(); j++) a(i, j) = drand48(); fout.write(a, "MyMatrix"); fout.close(); readMe(myfile); } PsimagLite-3.06/drivers/binaryRead.cpp000066400000000000000000000011201446452427400177500ustar00rootroot00000000000000#include "IoBinary.h" #include "Vector.h" typedef std::pair PairType; int main(int argc, char* argv[]) { if (argc < 2) return 1; String myfile(argv[1]); PsimagLite::IoBinary::In fin(myfile); while (true) { String label = fin.readNextLabel(); if (label == "NOTFOUND") break; std::cout << "label=" << label << "\n"; char check = 0; SizeType total = 0; PairType type; fin.readCheckTotalAndType(check, total, type); int check1 = check; std::cout << "check=" << check1 << " total=" << total << " type=" << fin.nameOfType(type) << "\n"; } } PsimagLite-3.06/drivers/calculator.cpp000066400000000000000000000014011446452427400200230ustar00rootroot00000000000000#include "AST/ExpressionForAST.h" #include "AST/PlusMinusMultiplyDivide.h" #include "PredicateAwesome.h" #include "PsimagLite.h" #ifdef USE_COMPLEX typedef std::complex ComplexOrRealType; #else typedef double ComplexOrRealType; #endif int main(int argc, char** argv) { if (argc < 2) return 1; typedef PsimagLite::Vector::Type VectorStringType; typedef PsimagLite::PlusMinusMultiplyDivide PrimitivesType; PsimagLite::String str(argv[1]); PsimagLite::replaceAll(str, "%t", "0.25"); VectorStringType ve; PsimagLite::split(ve, str, ":"); PrimitivesType primitives; PsimagLite::ExpressionForAST expresionForAST(ve, primitives); std::cout << argv[1] << "\t" << expresionForAST.exec() << "\n"; } PsimagLite-3.06/drivers/checkRunId.cpp000066400000000000000000000026441446452427400177230ustar00rootroot00000000000000#include "ApplicationInfo.h" #include "BitManip.h" #include #include void usage(const char* progName) { std::cerr << "Usage: " << progName << " -i number | -g times\n"; } bool checkRunId(PsimagLite::String id, PsimagLite::String progName) { PsimagLite::String str(id); int l = str.length(); if (l < 3) { std::cerr << progName << ": too short runId=" << id << "\n"; return false; } PsimagLite::String check(""); PsimagLite::String number(""); check += str[l - 2]; check += str[l - 1]; for (int i = 0; i < l - 2; ++i) number += str[i]; unsigned long int x = atol(number.c_str()); int bits = PsimagLite::BitManip::countKernighan(x); std::cout << number << " " << check << " " << bits << "\n"; // std::cout< v1(n, 1.0); std::vector v2(n, 1.1); std::vector v3; // multiplication by scalar v3 <= v2 * 1.2; std::cout << v3; // plus v3 <= v1 + v2; std::cout << v3; v3 <= v1 + 1.3 * v2; std::cout << v3; v3 <= 1.3 * v2 + v1; std::cout << v3; // // minus // v3 <= v1 - v2; // std::cout< m1(n, n); for (SizeType i = 0; i < n; ++i) { m1(i, i) = i; SizeType iPlus1 = i + 1; if (iPlus1 >= n) iPlus1 = 0; m1(i, iPlus1) = m1(iPlus1, i) = 0.1; } PsimagLite::Matrix m2; // multiplication by scalar m2 = m1 * 1.2; std::cout << m2; // plus PsimagLite::Matrix m3; m3 = m1 + m2; std::cout << m3; m3 = m1 + 1.3 * m2; std::cout << m3; m3 = 1.3 * m2 + m1; std::cout << "--------------\n"; std::cout << m3; std::cout << m2; m3 = 0.5 * (m3 - m2); std::cout << m3; std::cout << "--------------\n"; m3 += m2; std::cout << m3; m3 -= m2; std::cout << m3; std::cout << "--------------\n"; // minus tests omitted here // matrix * matrix m3 = m1 * m2; std::cout << m3; // matrix * vector std::vector v1(n, 3.0); std::vector v2; v2 <= m3* v1; std::cout << v2; v2 <= v1* m3; std::cout << v2; } template void createRandomCrs(PsimagLite::CrsMatrix& crs, SizeType seed, SizeType nonZeros, T maxValue) { srand48(seed); PsimagLite::Matrix m(crs.rows(), crs.cols()); for (SizeType i = 0; i < nonZeros; i++) { // pick a row SizeType row = SizeType(drand48() * m.rows()); // and a column SizeType col = SizeType(drand48() * m.cols()); // and a value T val = drand48() * maxValue; m(row, col) = val; } fullMatrixToCrsMatrix(crs, m); } template bool checkCrs(const PsimagLite::CrsMatrix& m, const PsimagLite::Matrix& fm) { PsimagLite::Matrix mf; crsMatrixToFullMatrix(mf, m); for (SizeType i = 0; i < fm.rows(); ++i) { for (SizeType j = 0; j < fm.cols(); ++j) { if (fabs(mf(i, j) - fm(i, j)) > 1e-6) { std::cout << mf; std::cout << fm; return false; } } } return true; } void testCrsMatrix() { SizeType n = 10; unsigned int long seed = 343981; double ratio = 0.5; SizeType nonZeros = SizeType(ratio * n * n); double maxValue = 10.0; PsimagLite::CrsMatrix m1(n, n); createRandomCrs(m1, seed, nonZeros, maxValue); PsimagLite::Matrix fm1; crsMatrixToFullMatrix(fm1, m1); // std::cout< m2(n, n); createRandomCrs(m2, seed, nonZeros, maxValue); PsimagLite::Matrix fm2; crsMatrixToFullMatrix(fm2, m2); // std::cout< m3 = m1 * m2; PsimagLite::Matrix fm3 = fm1 * fm2; std::cout << "CHECK PASSES=" << checkCrs(m3, fm3) << "\n"; // std::cout< m4 = 1.3 * m2; PsimagLite::Matrix fm4; fm4 = 1.3 * fm2; std::cout << "CHECK PASSES=" << checkCrs(m4, fm4) << "\n"; // std::cout< fm5; fm5 = 1.4 * fm1 * fm3; fm4 += fm5; // std::cout< #include #include #include using namespace PsimagLite; typedef double RealType; typedef TridiagonalMatrix TridiagonalMatrixType; typedef ContinuedFraction ContinuedFractionType; typedef ContinuedFractionCollection ContinuedFractionCollectionType; void usage(const char* progName) { std::cerr << "Usage: " << progName << " file1 file2\n"; } int main(int argc, char* argv[]) { if (argc < 2) { usage(argv[0]); return 1; } ContinuedFractionCollectionType cfCollection(FREQ_REAL); String s = "#Avector"; for (int x = 1; x < argc; x++) { IoSimple::In io(argv[x]); io.advance(s, IoSimple::In::LAST_INSTANCE); ContinuedFractionType cf(io); cfCollection.push(cf); } IoSimple::Out ioOut(std::cout); ioOut.setPrecision(12); cfCollection.write(ioOut); } PsimagLite-3.06/drivers/concurrencyTest.cpp000066400000000000000000000051561446452427400210770ustar00rootroot00000000000000// BEGIN LICENSE BLOCK /* Copyright (c) 2011 , UT-Battelle, LLC All rights reserved [PsimagLite, Version 1.0.0] ------------------------------------------------------------------ THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. Please see full open source license included in file LICENSE. ------------------------------------------------------------------ */ // END LICENSE BLOCK #include "Range.h" #include "String.h" #include "Vector.h" #include #include #include #include typedef double RealType; #ifdef USE_MPI #include "ConcurrencyMpi.h" typedef PsimagLite::ConcurrencyMpi ConcurrencyType; #else #include "ConcurrencySerial.h" typedef PsimagLite::ConcurrencySerial ConcurrencyType; #endif typedef PsimagLite::Vector::Type VectorType; void setVectors(PsimagLite::Vector::Type& vec, SizeType total1, SizeType total2) { VectorType series(total1 * total2); VectorType tmp(total2); SizeType k = 0; for (SizeType j = 0; j < total1; j++) { for (SizeType i = 0; i < total2; i++) { RealType val = (k < 2) ? 1 : series[k - 1] + series[k - 2]; tmp[i] = val; series[k++] = val; } vec.push_back(tmp); } } int main(int argc, char* argv[]) { if (argc < 4) { PsimagLite::String s(argv[0]); s += ": Needs total1, total2 and segmentSize as args\n"; throw PsimagLite::RuntimeError(s.c_str()); } typedef ConcurrencyType::CommType CommType; ConcurrencyType concurrency(argc, argv); SizeType total1 = atoi(argv[1]); SizeType total2 = atoi(argv[2]); SizeType ySize = atoi(argv[3]); std::pair comm = concurrency.newCommFromSegments(ySize); PsimagLite::Range range(0, total1, concurrency, comm.second); PsimagLite::Vector::Type vec; setVectors(vec, total1, total2); VectorType sum(total1); while (!range.end()) { SizeType i = range.index(); VectorType& v = vec[i]; PsimagLite::Range range2(0, total2, concurrency, comm.first); while (!range2.end()) { SizeType j = range2.index(); sum[i] += v[j]; std::cout << "i=" << i << " j=" << j << " comm1.rank=" << concurrency.rank(comm.first); std::cout << " comm2.rank=" << concurrency.rank(comm.second) << " world.rank=" << concurrency.rank() << "\n"; range2.next(); } concurrency.reduce(sum, comm.first); if (concurrency.root(comm.first)) std::cout << "sum[" << i << "]=" << sum[i] << "\n"; range.next(); } } PsimagLite-3.06/drivers/configure.ac000066400000000000000000000003341446452427400174600ustar00rootroot00000000000000AC_INIT(PsiDrivers, 1.0) dnl Switch to a C++ compiler, and check if it works. AC_LANG(C++) AC_PROG_CXX AX_LAPACK(, echo "ERROR: LAPACK not Found"; exit) dnl Process Makefile.in to create Makefile AC_OUTPUT(Makefile) PsimagLite-3.06/drivers/configure.pl000077500000000000000000000034651446452427400175230ustar00rootroot00000000000000#!/usr/bin/perl =pod Copyright (c) 2009-2017, UT-Battelle, LLC All rights reserved [PsimagLite, Version 1.] ********************************************************* THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. Please see full open source license included in file LICENSE. ********************************************************* =cut use warnings; use strict; use Getopt::Long qw(:config no_ignore_case); use lib "../../PsimagLite/scripts"; use NewMake; use PsiTag; my $flavor = NewMake::noFlavor(); my $usage = "USAGE: $0 [-f flavor]\n"; my $config; GetOptions('f=s' => \$flavor, 'c=s' => \$config) or die "$usage\n"; my @configFiles = ("./ConfigBase.psiTag"); push @configFiles, $config if (defined($config)); createMakefile(\@configFiles, $flavor); sub createMakefile { my ($configFiles, $flavor) = @_; my @drivers = qw(integrator sparseSolverTest testCRSMatrix combineContinuedFraction continuedFraction continuedFractionCollection range kernelPolynomial fit linearPrediction options randomTest svd testLapack threads loadImbalance testIsClass sumDecomposition calculator closuresTest base64test checkRunId testLanczos testExcitedLanczos testLanczosMatrixInFile nested testIoNg testIoNgBoolean affinityTest testPredicate isBlasThreaded testParallelizer2 testGemmR testGemmR2 testParallelSvd internode); my %args; $args{"code"} = "PsimagLite/drivers"; $args{"configFiles"} = $configFiles; $args{"flavor"} = $flavor; $args{"needsPsimagLiteLib"} = 1; NewMake::backupMakefile(); my $fh; open($fh, ">", "Makefile") or die "Cannot open Makefile for writing: $!\n"; NewMake::main($fh, \%args, \@drivers); } PsimagLite-3.06/drivers/continuedFraction.cpp000066400000000000000000000042141446452427400213550ustar00rootroot00000000000000// BEGIN LICENSE BLOCK /* Copyright (c) 2009 , UT-Battelle, LLC All rights reserved [PsimagLite, Version 1.0.0] ********************************************************* THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. Please see full open source license included in file LICENSE. ********************************************************* */ // END LICENSE BLOCK #include "ContinuedFraction.h" #include "Io/IoSimple.h" #include "TridiagonalMatrix.h" #include #include #include #include using namespace PsimagLite; typedef double RealType; typedef TridiagonalMatrix TridiagonalMatrixType; typedef ContinuedFraction ContinuedFractionType; void usage(const char* progName) { std::cerr << "Usage: " << progName << " -f file -b omega1"; std::cerr << " -e omega2 -s omegaStep -d delta\n"; std::cerr << "Conditions: omega10 delta>0\n"; } int main(int argc, char* argv[]) { int opt = 0; String file = ""; RealType wbegin = 0; RealType wend = 0; RealType wstep = 0; RealType delta = 0; while ((opt = getopt(argc, argv, "f:b:e:s:d:")) != -1) { switch (opt) { case 'f': file = optarg; break; case 'b': wbegin = atof(optarg); break; case 'e': wend = atof(optarg); break; case 's': wstep = atof(optarg); break; case 'd': delta = atof(optarg); break; default: usage(argv[0]); return 1; } } // sanity checks: if (file == "" || wbegin >= wend || wstep <= 0 || delta <= 0) { usage(argv[0]); return 1; } IoSimple::In io(file); ContinuedFractionType cf(io); typedef typename ContinuedFractionType::PlotParamsType PlotParamsType; typename ContinuedFractionType::PlotDataType v; PlotParamsType plotParams(wbegin, wend, wstep, delta, 0, 0); cf.plot(v, plotParams); for (SizeType x = 0; x < v.size(); x++) { std::cout << v[x].first << " " << PsimagLite::real(v[x].second); std::cout << " " << PsimagLite::imag(v[x].second) << "\n"; } } PsimagLite-3.06/drivers/continuedFractionCollection.cpp000066400000000000000000000063271446452427400234000ustar00rootroot00000000000000// BEGIN LICENSE BLOCK /* Copyright (c) 2009 , UT-Battelle, LLC All rights reserved [PsimagLite, Version 1.0.0] ********************************************************* THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. Please see full open source license included in file LICENSE. ********************************************************* */ // END LICENSE BLOCK #include "ContinuedFractionCollection.h" #include "ContinuedFraction.h" #include "Io/IoSimple.h" #include "TridiagonalMatrix.h" #include #include #include #include using namespace PsimagLite; typedef double RealType; typedef TridiagonalMatrix TridiagonalMatrixType; typedef ContinuedFraction ContinuedFractionType; typedef ContinuedFractionCollection ContinuedFractionCollectionType; typedef ContinuedFractionType::PlotParamsType PlotParamsType; void usage(const char* progName) { std::cerr << "Usage: " << progName << " -f file -b omega1"; std::cerr << " -e omega2 -s omegaStep -d delta -B beta -m matsubaras\n"; } void plotAll(const ContinuedFractionCollectionType& cfCollection, const PlotParamsType& params) { ContinuedFractionCollectionType::PlotDataType v; cfCollection.plot(v, params); std::cout.precision(12); for (SizeType x = 0; x < v.size(); x++) { std::cout << v[x].first << " " << PsimagLite::imag(v[x].second); std::cout << " " << PsimagLite::real(v[x].second) << "\n"; } } void plotOneByOne(const ContinuedFractionCollectionType& cfCollection, const PlotParamsType& params) { std::cout.precision(12); for (SizeType i = 0; i < cfCollection.size(); i++) { ContinuedFractionCollectionType::PlotDataType v; cfCollection.plotOne(i, v, params); for (SizeType x = 0; x < v.size(); x++) { std::cout << v[x].first << " " << PsimagLite::imag(v[x].second); std::cout << " " << PsimagLite::real(v[x].second) << "\n"; } } } int main(int argc, char* argv[]) { int opt = 0; String file = ""; RealType wbegin = 0; RealType wend = 0; RealType wstep = 0; RealType delta = 0; RealType beta = 0.0; SizeType matsubaras = 0; bool oneByOne = false; while ((opt = getopt(argc, argv, "f:b:e:s:d:m:B:1")) != -1) { switch (opt) { case 'f': file = optarg; break; case 'b': wbegin = atof(optarg); break; case 'e': wend = atof(optarg); break; case 's': wstep = atof(optarg); break; case 'd': delta = atof(optarg); break; case '1': oneByOne = true; break; case 'm': matsubaras = atoi(optarg); break; case 'B': beta = atof(optarg); break; default: usage(argv[0]); return 1; } } // sanity checks: bool real1 = (wbegin >= wend || wstep <= 0 || delta <= 0); bool imag1 = (beta <= 0 || matsubaras == 0); if (file == "" || (real1 & imag1)) { usage(argv[0]); return 1; } IoSimple::In io(file); ContinuedFractionCollectionType cfCollection(io); PlotParamsType params(wbegin, wend, wstep, delta, beta, matsubaras); if (!oneByOne) plotAll(cfCollection, params); else plotOneByOne(cfCollection, params); } PsimagLite-3.06/drivers/dataForAkimaSpline.txt000066400000000000000000000002141446452427400214260ustar00rootroot00000000000000#site=1 #timeSteps=5 #tau=0.025 0 0.0181906 0.425 0.0186353 0.45 0.0186353 0.875 0.0586719 0.9 0.0586719 1.2 0.139651 1.225 0.139651 PsimagLite-3.06/drivers/fit.cpp000066400000000000000000000154561446452427400164730ustar00rootroot00000000000000#include "Minimizer.h" #include "PsimagLite.h" #include "Vector.h" #include #include #include template class OracleData { public: typedef RealType_ RealType; typedef typename PsimagLite::Vector::Type VectorRealType; OracleData(PsimagLite::String file, RealType kf) : file_(file) { // kx omega real imag std::ifstream fin(file_.c_str()); while (!fin.eof()) { RealType tmp = 0.0; fin >> tmp; RealType kx = tmp; fin >> tmp; RealType omega = tmp; fin >> tmp; fin >> tmp; RealType value = tmp; if (fabs(kx - kf) >= 1e-6) continue; omegas_.push_back(omega); values_.push_back(value); } std::cerr << "#Found " << omegas_.size() << " omega values for kf=" << kf << "\n"; if (omegas_.size() == 0) err("No data found in " + file + "\n"); } const RealType& operator()(SizeType i) const { assert(i < values_.size()); return values_[i]; } const VectorRealType& omegas() const { return omegas_; } private: PsimagLite::String file_; VectorRealType omegas_; VectorRealType values_; }; template class FitData { typedef typename PsimagLite::Vector::Type VectorRealType; public: FitData(const VectorRealType& omegas, RealType mu, RealType kf, int ky) : omegas_(omegas) , mu_(mu) , ekf_(dispersion(kf, ky * M_PI) - mu) , initDelta_(1) , initGamma_(0.1) , anorm_(1.0) { // anorm_ = 1.0/sum(); std::cerr << "#FitData ctor(): ekf_= " << ekf_; std::cerr << " initDelta_= " << initDelta_ << " initGamma_= " << initGamma_; std::cerr << " mu= " << mu << "\n"; std::cout << "anorm=" << anorm_ << "\n"; } RealType operator()(SizeType i, const VectorRealType& v) const { assert(v.size() == 2); const RealType& omega = omegas_[i]; const RealType& delta = v[0]; const RealType& gamma = v[1]; return finternal(omega, delta, gamma); } RealType df(SizeType i, const VectorRealType& v, SizeType j) const { assert(v.size() == 2); const RealType& omega = omegas_[i]; const RealType& delta = v[0]; const RealType& gamma = v[1]; return (j == 0) ? dfDelta(omega, delta, gamma) : dfGamma(omega, delta, gamma); } SizeType size() const { return 2; } static void init(VectorRealType& x) { assert(x.size() == 2); x[0] = 1; x[1] = 0.1; } private: RealType finternal(RealType omega, RealType delta, RealType gamma) const { RealType gaom = gamma * omega; RealType num = (omega + ekf_) * gaom * 2.0 * anorm_ / M_PI; RealType omega2 = omega * omega; RealType phi2 = ekf_ * ekf_ + gamma * gamma + delta * delta; RealType den = square(omega2 - phi2) + 4 * gaom * gaom; return num / den; } RealType dfDelta(RealType omega, RealType delta, RealType gamma) const { RealType gaom = gamma * omega; RealType num = (omega + ekf_) * gaom * 2.0 * anorm_ / M_PI; RealType omega2 = omega * omega; RealType phi2 = ekf_ * ekf_ + gamma * gamma + delta * delta; RealType den = square(omega2 - phi2) + 4 * gaom * gaom; RealType numd = 4.0 * delta * (phi2 - omega2); return -num * numd / square(den); } RealType dfGamma(RealType omega, RealType delta, RealType gamma) const { RealType gaom = gamma * omega; RealType num0 = (omega + ekf_) * omega * 2.0 * anorm_ / M_PI; RealType omega2 = omega * omega; RealType phi2 = ekf_ * ekf_ + gamma * gamma + delta * delta; RealType den = square(omega2 - phi2) + 4.0 * gaom * gaom; RealType num = -num0 * gamma * (4 * (phi2 - omega2) * gamma + 8 * gamma * omega2); return num0 / den - num / square(den); } RealType dispersion(RealType kx, RealType ky) const { return -2 * cos(kx) - cos(ky); } RealType sum() const { SizeType n = omegas_.size(); RealType sum = 0; for (SizeType i = 0; i < n; ++i) sum += finternal(omegas_[i], initDelta_, initGamma_); return sum; } static RealType square(RealType x) { return x * x; } VectorRealType omegas_; RealType mu_; RealType ekf_; const RealType initDelta_; const RealType initGamma_; RealType anorm_; }; template class Fitter { typedef typename OracleType::RealType RealType; typedef typename OracleType::VectorRealType VectorRealType; class MyFunctionTest { public: typedef RealType FieldType; MyFunctionTest(const OracleType& od, const FitDataType& fd) : od_(od) , fd_(fd) { } RealType operator()(const VectorRealType& v) const { RealType sum = 0.0; SizeType n = od_.omegas().size(); for (SizeType i = 0; i < n; ++i) { RealType x = fabs(od_(i) - fd_(i, v)); sum += x * x; } return sum; } void df(VectorRealType& result, const VectorRealType& v) const { assert(result.size() == size()); for (SizeType j = 0; j < size(); ++j) { RealType sum = 0.0; SizeType n = od_.omegas().size(); for (SizeType i = 0; i < n; ++i) { // FIXME CHECK SIGN OF DERIVATIVE HERE RealType x = (fd_(i, v) - od_(i)) * fd_.df(i, v, j); sum += x; } result[j] = sum * 2.0; } } SizeType size() const { return 2; } private: const OracleType& od_; const FitDataType& fd_; }; public: Fitter(const OracleType& od, const FitDataType& fd) : od_(od) , fd_(fd) , results_(fd.size(), 0) { } void fit(SizeType maxIter) { FitDataType::init(results_); MyFunctionTest f(od_, fd_); PsimagLite::Minimizer min(f, maxIter); int iter = min.simplex(results_, 1e-5, 1e-7); if (iter < 0) std::cerr << "No minimum found\n"; std::cerr << "#Converged after " << iter << " iterations.\n"; std::cerr << "#Minimum is " << f(results_) << "\n"; std::ofstream of("test.out"); printComparison(of); } void fit2(SizeType maxIter) { FitDataType::init(results_); MyFunctionTest f(od_, fd_); PsimagLite::Minimizer min(f, maxIter); int iter = min.conjugateGradient(results_, 1e-3, 1e-3, 1e-3); if (iter < 0) std::cerr << "No minimum found\n"; } void print(std::ostream& os) const { if (results_.size() != 2) err("print results not size 2\n"); os << "delta=" << results_[0] << "\n"; os << "gamma=" << results_[1] << "\n"; } private: void printComparison(std::ostream& os) const { SizeType n = od_.omegas().size(); for (SizeType i = 0; i < n; ++i) os << od_.omegas()[i] << " " << od_(i) << " " << fd_(i, results_) << "\n"; } const OracleType& od_; const FitDataType& fd_; VectorRealType results_; }; int main(int argc, char** argv) { if (argc != 5) { std::cerr << "USAGE: " << argv[0] << " filename.gnuplot mu kf ky\n"; return 1; } double mu = atof(argv[2]); double kf = atof(argv[3]); int ky = atoi(argv[4]); OracleData od(argv[1], kf); FitData fit(od.omegas(), mu, kf, ky); Fitter, FitData> fitter(od, fit); SizeType maxIter = 1000; fitter.fit(maxIter); fitter.print(std::cout); } PsimagLite-3.06/drivers/integrator.cpp000066400000000000000000000017321446452427400200570ustar00rootroot00000000000000#include "Integrator.h" template class SquareFunction { struct Params { Params(RealType_ p_) : p(p_) { } RealType_ p; }; public: typedef RealType_ RealType; SquareFunction(RealType p) : p_(p) { } static RealType function(RealType x, void* vp) { Params* p = static_cast(vp); return x * x * p->p; } Params& params() { return p_; } private: Params p_; }; int main(int argc, char** argv) { if (argc != 4) { std::cerr << "USAGE: " << argv[0] << " x0 total xstep\n"; return 1; } double x0 = atof(argv[1]); SizeType total = atoi(argv[2]); double xstep = atof(argv[3]); typedef SquareFunction SquareFunctionType; SquareFunctionType squareFunction(3.0); PsimagLite::Integrator integrator(squareFunction); PsimagLite::Vector::Type pts(2, 0); for (SizeType i = 0; i < total; ++i) { pts[1] = x0 + i * xstep; std::cout << pts[1] << " " << integrator(pts) << "\n"; } } PsimagLite-3.06/drivers/internode.cpp000066400000000000000000000014461446452427400176720ustar00rootroot00000000000000#include "InterNode.h" #include "PsimagLite.h" int main(int argc, char* argv[]) { PsimagLite::PsiApp psiApp("internode", &argc, &argv, 1); if (argc < 2) { std::cerr << "USAGE " << argv[0] << " number\n"; return 1; } const SizeType n = atoi(argv[1]); // original for (SizeType i = 0; i < n; ++i) { std::cout << i; } std::cout << "\n--------------------------\n"; // lambda PsimagLite::InterNode<> internode(PsimagLite::MPI::COMM_WORLD); internode.parallelFor(0, n, [](SizeType i, SizeType) { std::cout << i; }); std::cout << "\n--------------------------\n"; size_t len = 1024; char* name = new char[len + 1]; int x = gethostname(name, len); if (x != 0) std::cerr << argv[0] << ": Could not gethostname\n"; else std::cout << name << "\n"; delete[] name; name = nullptr; } PsimagLite-3.06/drivers/isBlasThreaded.cpp000066400000000000000000000051151446452427400205560ustar00rootroot00000000000000#include "BLAS.h" #include "Matrix.h" #include "Random48.h" #include // for atoi #define USE_PTHREADS_OR_NOT_NG #include "Parallelizer.h" typedef double MyRealType; typedef PsimagLite::Matrix MatrixType; class MyBlasWrapper { public: typedef PsimagLite::Vector::Type VectorMatrixType; MyBlasWrapper(SizeType m, SizeType n, SizeType k, SizeType total) : a_(total) , b_(total) , c_(total) , myrandom48_(1234) { for (SizeType i = 0; i < total; ++i) { SizeType factor = (i & 1) ? 2 : 1; a_[i] = new MatrixType(m * factor, k * factor); b_[i] = new MatrixType(k * factor, n * factor); c_[i] = new MatrixType(m * factor, n * factor); fillMatrix(*(a_[i])); fillMatrix(*(b_[i])); } } ~MyBlasWrapper() { const SizeType total = a_.size(); for (SizeType i = 0; i < total; ++i) { delete a_[i]; delete b_[i]; delete c_[i]; a_[i] = b_[i] = c_[i] = 0; } } SizeType tasks() const { return a_.size(); } void doTask(SizeType ind, SizeType) { assert(a_[ind] && b_[ind] && c_[ind]); SizeType mm = a_[ind]->rows(); SizeType nn = b_[ind]->cols(); SizeType kk = a_[ind]->cols(); assert(kk == b_[ind]->rows()); assert(c_[ind]->rows() == mm && c_[ind]->cols() == nn); SizeType lda = a_[ind]->rows(); SizeType ldb = b_[ind]->rows(); SizeType ldc = c_[ind]->rows(); MyRealType* aptr = &(a_[ind]->operator()(0, 0)); MyRealType* bptr = &(b_[ind]->operator()(0, 0)); MyRealType* cptr = &(c_[ind]->operator()(0, 0)); psimag::BLAS::GEMM('N', 'N', mm, // rows of op(A) nn, // columns of op(B) kk, // columns of op(A) 1.0, aptr, lda, // first dimension of A bptr, ldb, // first dimension of B 0.0, cptr, ldc); // first dimension of C *(a_[ind]) = *(b_[ind]); *(b_[ind]) = *(c_[ind]); } private: void fillMatrix(MatrixType& m) { for (SizeType j = 0; j < m.cols(); ++j) for (SizeType i = 0; i < m.rows(); ++i) m(i, j) = myrandom48_(); } VectorMatrixType a_; VectorMatrixType b_; VectorMatrixType c_; PsimagLite::Random48 myrandom48_; }; int main(int argc, char** argv) { if (argc < 6) { std::cerr << "USAGE: " << argv[0] << " m k n total threads\n"; return 1; } SizeType m = atoi(argv[1]); SizeType k = atoi(argv[2]); SizeType n = atoi(argv[3]); SizeType total = atoi(argv[4]); SizeType threads = atoi(argv[5]); PsimagLite::CodeSectionParams codeSections(threads); PsimagLite::Parallelizer parallel(codeSections); MyBlasWrapper myblasWrapper(m, n, k, total); parallel.loopCreate(myblasWrapper); } PsimagLite-3.06/drivers/kernelPolynomial.cpp000066400000000000000000000052661446452427400212330ustar00rootroot00000000000000// BEGIN LICENSE BLOCK /* Copyright (c) 2011 , UT-Battelle, LLC All rights reserved [PsimagLite, Version 1.0.0] ------------------------------------------------------------------ THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. Please see full open source license included in file LICENSE. ------------------------------------------------------------------ */ // END LICENSE BLOCK #include "ChebyshevSerializer.h" #include "Io/IoSimple.h" #include #include #include #include void usage(const char* progName) { std::cerr << "Usage: " << progName << " -f file -b omega1"; std::cerr << " -e omega2 -s omegaStep \n"; std::cerr << "Conditions: omega10 \n"; } int main(int argc, char* argv[]) { int opt = 0; PsimagLite::String file = ""; typedef double RealType; typedef PsimagLite::Vector::Type VectorType; RealType wbegin = 0; RealType wend = 0; RealType wstep = 0; typedef PsimagLite::ChebyshevSerializer ChebyshevSerializerType; typedef ChebyshevSerializerType::KernelParametersType KernelParametersType; SizeType type = KernelParametersType::JACKSON; RealType lambda = 0.0; bool makeZero = false; SizeType cutoff = 0; while ((opt = getopt(argc, argv, "f:b:e:s:c:l:zd")) != -1) { switch (opt) { case 'f': file = optarg; break; case 'b': wbegin = atof(optarg); break; case 'e': wend = atof(optarg); break; case 's': wstep = atof(optarg); break; case 'c': cutoff = atoi(optarg); break; case 'l': type = KernelParametersType::LORENTZ; lambda = atof(optarg); break; case 'd': type = KernelParametersType::DIRICHLET; break; case 'z': makeZero = true; break; default: usage(argv[0]); return 1; } } // sanity checks: if (file == "" || wbegin >= wend || wstep <= 0) { usage(argv[0]); return 1; } PsimagLite::IoSimple::In io(file); typedef PsimagLite::ChebyshevSerializer ChebyshevSerializerType; io.advance(ChebyshevSerializerType::stringMarker(), PsimagLite::IoSimple::In::LAST_INSTANCE); ChebyshevSerializerType chebyshevSerializer(io); ChebyshevSerializerType::PlotParamsType params(wbegin, wend, wstep, 0.0, 0.0, 0); ChebyshevSerializerType::PlotDataType v; KernelParametersType kernelParams(type, cutoff, lambda); chebyshevSerializer.plot(v, params, kernelParams); for (SizeType x = 0; x < v.size(); x++) { RealType tmp = v[x].second; if (tmp < 0 && makeZero) tmp = 0; std::cout << v[x].first << " " << tmp << "\n"; } } PsimagLite-3.06/drivers/linearPrediction.cpp000066400000000000000000000037471446452427400212040ustar00rootroot00000000000000// BEGIN LICENSE BLOCK /* Copyright (c) 2009 , UT-Battelle, LLC All rights reserved [PsimagLite, Version 1.0.0] ********************************************************* THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. Please see full open source license included in file LICENSE. ********************************************************* */ // END LICENSE BLOCK #include "LinearPrediction.h" #include "Io/IoSimple.h" #include #include #include #include typedef double FieldType; typedef PsimagLite::LinearPrediction LinearPredictionType; void usage(const char* progName) { std::cerr << "Usage: " << progName << " -f file -l label -p n -q q[>1]\n"; } int main(int argc, char* argv[]) { int opt = 0; PsimagLite::String file = ""; PsimagLite::String label = ""; SizeType p = 0; SizeType q = 2; while ((opt = getopt(argc, argv, "f:p:l:q:")) != -1) { switch (opt) { case 'f': file = optarg; break; case 'l': label = optarg; break; case 'p': p = atoi(optarg); break; case 'q': q = atoi(optarg); break; default: usage(argv[0]); return 1; } } // sanity checks: if (file == "" || label == "" || p == 0 || q < 2) { usage(argv[0]); return 1; } PsimagLite::IoSimple::In io(file); PsimagLite::Vector::Type y; io.read(y, label); SizeType n = y.size(); std::cout << "#Found " << n << " points in file " << file << "\n"; LinearPredictionType linearPrediction(y, q); linearPrediction.predict(q); for (SizeType i = 0; i < p; i++) { linearPrediction.linearPredictionfunction(y, q); linearPrediction.predict(q); } for (SizeType i = 0; i < p + n; i++) { std::cout << linearPrediction(i) << "\n"; } } // Test Function in series.txt is: f[i] = // 0.5*(cos((i-1)*pi/100)+cos((i-1)*pi/20))*exp(-(i-1)/100) PsimagLite-3.06/drivers/loadImbalance.cpp000066400000000000000000000044431446452427400204160ustar00rootroot00000000000000/* Copyright (c) 2009-2017, UT-Battelle, LLC All rights reserved [PsimagLite, Version 1.] ********************************************************* THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. Please see full open source license included in file LICENSE. ********************************************************* */ #include "Concurrency.h" #include #include #define USE_PTHREADS_OR_NOT_NG #include "LoadBalancerWeights.h" #include "Parallelizer.h" class MyHelper { typedef PsimagLite::Concurrency ConcurrencyType; typedef PsimagLite::Vector::Type VectorSizeType; public: MyHelper(SizeType ntasks, SizeType nthreads) : weight_(ntasks) , x_(nthreads, 0) { srand48(1234); for (SizeType i = 0; i < ntasks; ++i) { double x = 10 * drand48(); weight_[i] = 1 + static_cast(x); std::cout << weight_[i] << " "; } std::cout << "\n"; } SizeType tasks() const { return weight_.size(); } int result() const { return x_[0]; } const VectorSizeType& weights() { return weight_; } void doTask(SizeType taskNumber, SizeType threadNum) { for (SizeType i = 0; i < weight_[taskNumber]; ++i) x_[threadNum] += (taskNumber + i); } void sync() { for (SizeType i = 1; i < x_.size(); ++i) x_[0] += x_[i]; } private: VectorSizeType weight_; VectorSizeType x_; }; // class MyHelper int main(int argc, char* argv[]) { typedef PsimagLite::Concurrency ConcurrencyType; if (argc != 3) { std::cout << "USAGE: " << argv[0] << " nthreads ntasks\n"; return 1; } SizeType nthreads = atoi(argv[1]); SizeType ntasks = atoi(argv[2]); ConcurrencyType concurrency(&argc, &argv, nthreads); typedef MyHelper HelperType; typedef PsimagLite::Parallelizer ParallelizerType; ParallelizerType threadObject(ConcurrencyType::codeSectionParams); HelperType helper(ntasks, nthreads); std::cout << "Using " << threadObject.name(); std::cout << " with " << nthreads << " threads.\n"; threadObject.loopCreate(helper, helper.weights()); helper.sync(); std::cout << "Sum of all tasks= " << helper.result() << "\n"; } PsimagLite-3.06/drivers/make.pl000066400000000000000000000011261446452427400164440ustar00rootroot00000000000000#!/usr/bin/perl use strict; use warnings; use lib '../scripts'; use Make; my @drivers = qw/integrator sparseSolverTest testCRSMatrix minimizer combineContinuedFraction continuedFractionCollection range kernelPolynomial linearPrediction options randomTest svd testLapack threads testIsClass sumDecomposition calculator closuresTest base64test testIoNg fit/; my $fh; open($fh, ">", "Makefile") or die "$0: Cannot open Makefile for writing\n"; Make::newMake($fh, \@drivers, {"code" => "PsimagLite"}); close($fh); print "$0: Makefile has been written\n"; PsimagLite-3.06/drivers/matrix.txt000066400000000000000000000043401446452427400172400ustar00rootroot0000000000000016 16 (0.75,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0.25,0) (0.5,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0.5,0) (-0.25,0) (0,0) (0.5,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0.25,0) (0,0) (0.5,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0.5,0) (0,0) (-0.25,0) (0,0) (0,0) (0,0) (0.5,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0.5,0) (0,0) (-0.75,0) (0.5,0) (0,0) (0,0) (0.5,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0.5,0) (-0.25,0) (0,0) (0,0) (0,0) (0.5,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0.25,0) (0,0) (0,0) (0,0) (0.5,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0.5,0) (0,0) (0,0) (0,0) (0.25,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0.5,0) (0,0) (0,0) (0,0) (-0.25,0) (0.5,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0.5,0) (0,0) (0,0) (0.5,0) (-0.75,0) (0,0) (0.5,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0.5,0) (0,0) (0,0) (0,0) (-0.25,0) (0,0) (0.5,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0.5,0) (0,0) (0.25,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0.5,0) (0,0) (-0.25,0) (0.5,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0.5,0) (0.25,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0.75,0) PsimagLite-3.06/drivers/minimizer.cpp000066400000000000000000000021371446452427400177040ustar00rootroot00000000000000#include "Minimizer.h" #include "Vector.h" // #include "Square.h" template T square(const T& t1) { return t1 * t1; } template std::ostream& operator<<(std::ostream& os, const typename PsimagLite::Vector::Type& v) { os << v.size() << "\n"; for (SizeType i = 0; i < v.size(); i++) os << v[i] << " "; os << "\n"; return os; } using namespace PsimagLite; typedef double RealType; class MyFunctionTest { public: typedef double FieldType; template FieldType operator()(const SomeVectorType& v) const { return square(v[0] - 2) + square(v[1] - 3); } SizeType size() const { return 2; } }; int main(int argc, char* argv[]) { SizeType n = 2; typename Vector::Type x(n); // inital guess: for (SizeType i = 0; i < n; i++) x[i] = drand48(); SizeType maxIter = 100; MyFunctionTest f; Minimizer min(f, maxIter); int iter = min.simplex(x, 1e-3, 1e-5); if (iter < 0) { std::cout << "No minimum found\n"; return 1; } std::cout << "Minimum found after " << iter << " iterations.\n"; std::cout << x; } PsimagLite-3.06/drivers/myApp01.cpp000066400000000000000000000003461446452427400171300ustar00rootroot00000000000000#include "PsimagLite.h" using namespace PsimagLite; // g++ myApp01.cpp -o myApp01 -I../src -L../lib -lpsimaglite int main(int argc, char** argv) { SizeType nthreads = 1; PsiApp application("DMRG++", &argc, &argv, nthreads); } PsimagLite-3.06/drivers/nested.cpp000066400000000000000000000062221446452427400171620ustar00rootroot00000000000000/* Copyright (c) 2009-2017, UT-Battelle, LLC All rights reserved [PsimagLite, Version 1.] ********************************************************* THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. Please see full open source license included in file LICENSE. ********************************************************* */ #include "../src/Concurrency.h" #include #include #define USE_PTHREADS_OR_NOT_NG #include "../src/Parallelizer.h" class InnerHelper { typedef PsimagLite::Concurrency ConcurrencyType; typedef PsimagLite::Vector::Type VectorSizeType; public: InnerHelper(SizeType ntasks, SizeType nthreads, int outerTask) : ntasks_(ntasks) , x_(nthreads, 0) , offset_(outerTask * ntasks) { } SizeType tasks() const { return ntasks_; } int result() const { return x_[0]; } void doTask(SizeType taskNumber, SizeType threadNum) { x_[threadNum] += taskNumber + offset_; } void sync() { for (SizeType i = 1; i < x_.size(); ++i) x_[0] += x_[i]; } private: SizeType ntasks_; VectorSizeType x_; SizeType offset_; }; // class InnerHelper class MyHelper { typedef PsimagLite::Concurrency ConcurrencyType; typedef PsimagLite::Vector::Type VectorSizeType; public: MyHelper(SizeType ntasks, SizeType nthreadsOuter, SizeType ntasksInner, SizeType nthreadsInner) : ntasks_(ntasks) , x_(nthreadsOuter, 0) , ntasksInner_(ntasksInner) , nthreadsInner_(nthreadsInner) { } SizeType tasks() const { return ntasks_; } int result() const { return x_[0]; } void doTask(SizeType taskNumber, SizeType threadNum) { typedef PsimagLite::Parallelizer ParallelizerType; PsimagLite::CodeSectionParams cs(nthreadsInner_); ParallelizerType threadObject(cs); InnerHelper helper(ntasksInner_, nthreadsInner_, taskNumber); threadObject.loopCreate(helper); helper.sync(); x_[threadNum] += helper.result(); } void sync() { for (SizeType i = 1; i < x_.size(); ++i) x_[0] += x_[i]; } private: SizeType ntasks_; VectorSizeType x_; SizeType ntasksInner_; SizeType nthreadsInner_; }; // class MyHelper int main(int argc, char* argv[]) { typedef PsimagLite::Concurrency ConcurrencyType; if (argc != 5) { std::cout << "USAGE: " << argv[0] << " threadsOuter tasksOuter threadsInner tasksInner\n"; return 1; } SizeType nthreadsOuter = atoi(argv[1]); SizeType ntasks = atoi(argv[2]); SizeType nthreadsInner = atoi(argv[3]); SizeType ntasksInner = atoi(argv[4]); ConcurrencyType concurrency(&argc, &argv, 1); typedef MyHelper HelperType; typedef PsimagLite::Parallelizer ParallelizerType; PsimagLite::CodeSectionParams cs(nthreadsOuter); ParallelizerType threadObject(cs); HelperType helper(ntasks, nthreadsOuter, ntasksInner, nthreadsInner); std::cout << "Using " << threadObject.name(); std::cout << " with " << nthreadsOuter << " threads.\n"; threadObject.loopCreate(helper); helper.sync(); std::cout << "Sum of all tasks= " << helper.result() << "\n"; } PsimagLite-3.06/drivers/newconfigure.pl000077500000000000000000000011541446452427400202260ustar00rootroot00000000000000#!/usr/bin/perl =pod Copyright (c) 2009-2018, UT-Battelle, LLC All rights reserved [DMRG++, Version 5.] ********************************************************* THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. Please see full open source license included in file LICENSE. ********************************************************* =cut use warnings; use strict; die "$0: Please use configure.pl instead of this program\n"; PsimagLite-3.06/drivers/openblasConfig.cpp000066400000000000000000000003751446452427400206340ustar00rootroot00000000000000#include #include // #include int main() { std::cout << "openblas_get_parallel= " << openblas_get_parallel() << "\n"; std::cout << "openblas_get_config= " << openblas_get_config() << "\n"; } PsimagLite-3.06/drivers/options.cpp000066400000000000000000000011741446452427400173740ustar00rootroot00000000000000#include "Options.h" #include int main(int argc, char* argv[]) { if (argc < 2) { std::cerr << "USAGE is " << argv[0] << " comma,separated,list,of,options\n"; return 1; } PsimagLite::Vector::Type registerOpts; registerOpts.push_back("fast"); registerOpts.push_back("verbose"); registerOpts.push_back("hasthreads"); PsimagLite::Options::Writeable optWriteable( registerOpts, PsimagLite::Options::Writeable::STRICT); PsimagLite::String myoptions(argv[1]); PsimagLite::Options::Readable optsReadable(optWriteable, myoptions); std::cout << "fast=" << optsReadable.isSet("fast") << "\n"; } PsimagLite-3.06/drivers/randomTest.cpp000066400000000000000000000004551446452427400200220ustar00rootroot00000000000000#include "Random48.h" #include #include using namespace PsimagLite; typedef double RealType; typedef Random48 RandomType; int main(int, char* argv[]) { RandomType rng(100); rng.seed(std::atoi(argv[1])); RealType x = rng.random(); std::cout << "x=" << x << "\n"; } PsimagLite-3.06/drivers/range.cpp000066400000000000000000000044441446452427400170000ustar00rootroot00000000000000/** How to compile and run this driver * * Serial version: * * g++ -g3 -DNDEBUG -Werror -Wall -I../src \ * -lm -lpthread range.cpp -o range \ * -lblas -llapack * * And run it with: * * ./range * * Parallel version: * * mpicxx -DUSE_MPI -g3 -DNDEBUG -Werror -Wall -I../src \ * -lm -lpthread range.cpp -o range \ * -lblas -llapack * * And run it with: * * your batch system script * */ #define USE_PTHREADS_OR_NOT_NG #include "Concurrency.h" #include "Parallelizer.h" #include #include class MyLoop { typedef PsimagLite::Concurrency ConcurrencyType; public: MyLoop(SizeType nthreads, SizeType total) : sum_(ConcurrencyType::storageSize(nthreads)) , v_(total, 0) { } SizeType tasks() const { return v_.size(); } void doTask(SizeType taskNumber, SizeType threadNum) { sleep(1); SizeType ind = ConcurrencyType::storageIndex(threadNum); sum_[ind] += taskNumber; v_[taskNumber] = taskNumber * taskNumber; } void sync() { if (ConcurrencyType::hasPthreads()) { SizeType tmp = PsimagLite::sum(sum_); sum_[0] = tmp; } if (ConcurrencyType::hasMpi()) { SizeType tmp = sum_[0]; PsimagLite::MPI::allReduce(tmp); sum_[0] = tmp; PsimagLite::MPI::allReduce(v_); } } SizeType sum() const { assert(sum_.size() > 0); return sum_[0]; } const PsimagLite::Vector::Type& v() const { return v_; } private: PsimagLite::Vector::Type sum_; PsimagLite::Vector::Type v_; }; int main(int argc, char* argv[]) { typedef PsimagLite::Concurrency ConcurrencyType; SizeType nthreads = 1; if (argc == 3) nthreads = atoi(argv[2]); ConcurrencyType concurrency(&argc, &argv, nthreads); typedef MyLoop HelperType; typedef PsimagLite::Parallelizer ParallelizerType; ParallelizerType threadObject(ConcurrencyType::codeSectionParams); if (argc < 2) return 1; SizeType total = atoi(argv[1]); HelperType helper(nthreads, total); threadObject.loopCreate(helper); helper.sync(); SizeType sum = helper.sum(); if (ConcurrencyType::root()) { std::cout << "Using " << threadObject.name() << " mode= " << ConcurrencyType::mode; std::cout << " with " << nthreads; std::cout << " threads or mpi procs.\n"; std::cout << "sum=" << sum << "\n"; std::cout << helper.v(); } } PsimagLite-3.06/drivers/rungeKuttaTest.cpp000066400000000000000000000067511446452427400207000ustar00rootroot00000000000000#include "RungeKutta.h" #include "IoSimple.h" #include "Matrix.h" #include "Vector.h" #include #include #include // authored by K.A.A template class GammaCiCj { typedef typename MatrixType::value_type ComplexOrRealType; public: GammaCiCj(MatrixType& T, VectorType& V, VectorType& W, const RealType& omega) : T_(T) , V_(V) , W_(W) , mV_(V.size(), V.size()) , mW_(W.size(), W.size()) , omega_(omega) { assert(V_.size() == W_.size()); for (SizeType i = 0; i < mV_.n_row(); i++) { for (SizeType j = 0; j < mV_.n_col(); j++) { mV_(i, j) = V_[j] - V_[i]; mW_(i, j) = W_[j] - W_[i]; } } } MatrixType operator()(const RealType& t, const MatrixType& y) const { ComplexOrRealType c(0., -1.); MatrixType tmp = (-1.0) * (T_ * y); // MatrixType yTranspose; // transposeConjugate(yTranspose,y); tmp += y * T_; for (SizeType i = 0; i < tmp.n_row(); i++) for (SizeType j = 0; j < tmp.n_col(); j++) tmp(i, j) += mV_(i, j) * y(i, j) + mW_(i, j) * cos(omega_ * t) * y(i, j); return c * tmp; } private: const MatrixType& T_; const VectorType& V_; const VectorType& W_; MatrixType mV_; MatrixType mW_; RealType omega_; }; // class GammaCiCj #ifndef USE_FLOAT typedef double RealType; #else typedef float RealType #endif typedef std::complex ComplexOrRealType; // typedef RealType ComplexOrRealType; typedef PsimagLite::Vector::Type VectorType; typedef PsimagLite::Matrix MatrixType; typedef GammaCiCj GammaCiCjType; typedef PsimagLite::IoSimple::In IoInType; void usage(const char* progName) { std::cerr << "Usage: " << progName << " -f file -i file2"; std::cerr << " -b t1 -e te -s ts \n"; } int main(int argc, char* argv[]) { int opt; PsimagLite::String file = ""; RealType wbegin = 0.; RealType wend = 10.; RealType wstep = 0.01; PsimagLite::String file2 = ""; while ((opt = getopt(argc, argv, "f:i:b:e:s:")) != -1) { switch (opt) { case 'f': file = optarg; break; case 'b': wbegin = atof(optarg); break; case 'e': wend = atof(optarg); break; case 's': wstep = atof(optarg); break; case 'i': file2 = optarg; break; default: usage(argv[0]); return 1; } } // sanity checks: if (file == "" || file2 == "" || wend <= wbegin || wstep < 0) { usage(argv[0]); return 1; } IoInType io(file); SizeType N; io.readline(N, "TotalNumberOfSites="); RealType hopping = 1.0; MatrixType T(N, N); for (SizeType i = 0; i < N - 1; i++) T(i, i + 1) = T(i + 1, i) = hopping; VectorType V; io.read(V, "potentialV"); if (V.size() > N) V.resize(N); VectorType W; io.read(W, "PotentialT"); assert(W.size() == N); RealType omega; io.readline(omega, "omega="); GammaCiCjType f(T, V, W, omega); PsimagLite::RungeKutta rk(f, wstep); MatrixType y0; IoInType io2(file2); io2.read(y0, "MatrixCiCj"); for (SizeType i = 0; i < y0.n_row(); i++) { for (SizeType j = 0; j < y0.n_col(); j++) { // if (i==j) y0(i,j) = 1.-y0(i,j); // if (i!=j) y0(i,j) = -y0(i,j); } } PsimagLite::Vector::Type result; rk.solveEx(result, wbegin, wend, y0); for (SizeType i = 0; i < result.size(); i++) { RealType time = wbegin + wstep * i; std::cout << time << " "; for (SizeType j = 0; j < result[i].size(); j++) std::cout << PsimagLite::real(result[i][j]) << " "; std::cout << "\n"; } } PsimagLite-3.06/drivers/series.txt000066400000000000000000000014611446452427400172270ustar00rootroot00000000000000Series 50 1 0.9837109906618 0.9552444053212 0.9154059818405 0.8652541558705 0.8060694941695 0.7393192992506 0.6666183469137 0.5896867938457 0.5103063412053 0.4302757613054 0.3513668881767 0.2752821396547 0.2036145800083 0.1378114499733 0.07914198783209 0.02867024385213 -0.01276654573324 -0.04457360629771 -0.06640802967052 -0.07818183001025 -0.08005870195437 -0.07244468542249 -0.05597308654312 -0.03148413783927 -4.32321280481e-17 0.03730419034575 0.07913243961241 0.1241023338419 0.1707809038286 0.2177210123731 0.2634973624311 0.3067412520585 0.3461732500491 0.3806330334234 0.4091057124367 0.4307440681104 0.4448862387402 0.4510685124194 0.4490330092085 0.4387301659654 0.4203160658007 0.394144779489 0.3607560049616 0.3208584004382 0.2753091043404 0.225090018715 0.1712815007022 0.1150341572763 0.0575394711582 PsimagLite-3.06/drivers/sfinaeHasMember.cpp000066400000000000000000000013331446452427400207270ustar00rootroot00000000000000#include #include // SFINAE test // source: // https://stackoverflow.com/questions/257288/is-it-possible-to-write-a-template-to-check-for-a-functions-existence template class has_helloworld { typedef char one; struct two { char x[2]; }; template static one test(typeof(&C::helloworld)); template static two test(...); public: enum { value = sizeof(test(0)) == sizeof(char) }; }; class A { public: int helloworld() const { return 42; } }; class B { }; template typename std::enable_if::value, int>::type f(const T& t) { return t.helloworld(); } int main() { A a; std::cout << f(a) << "\n"; // B b; // f(b); } PsimagLite-3.06/drivers/small.jsn000066400000000000000000000064301446452427400170210ustar00rootroot00000000000000{"programSpecific": {"DCA": {"options" : {"twoparticle":"off", "haverootname":"on" }, "outputfilename" : "output", "control" : {"initSigma" : "zero", "numberOfPerturbations" : 1, "selfConsistent": { "iterations" : 3, "convergence" : 0.75, "numberOfSweepsPerMeasurement" : 1, "maxNumberOfSweepsPerMeasurement" : 40 }, "observation" : { "measurements" : 2, "warm1" : 2, "warm2" : 2, "numberOfSweepsReComp" : 16}, "dcaMinError" : 1e-6, "coarseGrainFrequencyType" : "complex", "updateblock" : 32, "NBlock" : 32, "use_dgemv" : 1, "use_dgemm" : 1, "isDisorderPresent" : 0, "autoCorrelationType" : 1, "lowPassFilter" : 0, "hfSigmaCondType" : 1, "ftGreensCondType" : 1, "adjustChemicalPotential": 0, "bareOrbitalEnergy" : 0.0, "tprime" : 0.0, "density" : 1.0, "orbitalOccupancy" : 1, "numPointsInBath" : 4, "totalBins" : 10, "iDelta" : 1e-6}, "domains": {"NBlock" : 32, "phaseSelect" : 4, "numberOfTimes" : 20, "inverseTemperature" : 1.5, "frequencyType" : "complex", "nFinePoints" : 2500, "matsubaras" : 800, "realFrequencyBound" : 10.5, "realFrequencyStep" : 0.5, "numMeshPointsPerOrigLatticeCell" : 10000}, "geometry": {"dimension" : 2, "groupActionType" : "PointGroupOnly", "LatticeParameters" : { "a" : 1.0, "b" : 1.0, "alpha": 90.0}, "SuperLatticeBasis": {"A": [2, 0], "B": [0, 2]}}, "hubbard": {"type" : "explicit", "configurations" : [[2.0,2.0,2.0,2.0]]}, "potential": {"type" : "explicit", "configurations" : [[0.0,0.0,0.0,0.0]]}, "phase": {"type" : "explicit", "configurations" : [[0.0,0.0]]}, "test": {"rows" : 3, "cols" : 3, "data" : array([[0.0,0.0,1.3], [0.0,0.0,1.3], [0.0,0.0,1.3]]) } } } } PsimagLite-3.06/drivers/sparseSolverTest.cpp000066400000000000000000000070751446452427400212370ustar00rootroot00000000000000// BEGIN LICENSE BLOCK /* Copyright (c) 2009 , UT-Battelle, LLC All rights reserved [PsimagLite, Version 1.0.0] ********************************************************* THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. Please see full open source license included in file LICENSE. ********************************************************* */ // END LICENSE BLOCK #include "CrsMatrix.h" #include "DavidsonSolver.h" #include "LanczosSolver.h" #include "ParametersForSolver.h" #include "PsimagLite.h" #include "Random48.h" using namespace PsimagLite; typedef double RealType; typedef double ComplexOrRealType; typedef ParametersForSolver ParametersForSolverType; typedef Vector::Type VectorType; typedef CrsMatrix SparseMatrixType; typedef LanczosOrDavidsonBase SparseSolverType; typedef LanczosSolver LanczosSolverType; typedef DavidsonSolver DavidsonSolverType; void usage(const char* progName) { std::cerr << "Usage: " << progName << " -n rank [-x] [-d ] [-c max_columns] [-m max_value] [-r seed]\n"; exit(1); } int main(int argc, char* argv[]) { int opt = 0; bool useDavidson = false; SizeType n = 0; RealType maxValue = 0; SizeType maxCol = 0; SizeType seed = 0; bool lotaMemory = true; while ((opt = getopt(argc, argv, "n:c:m:r:dx")) != -1) { switch (opt) { case 'd': useDavidson = true; break; case 'n': n = atoi(optarg); break; case 'c': maxCol = atoi(optarg); break; case 'm': maxValue = atof(optarg); break; case 'r': seed = atoi(optarg); break; case 'x': lotaMemory = false; break; default: usage(argv[0]); return 1; } } // sanity checks if (n == 0) usage(argv[0]); if (maxCol == 0) maxCol = 1 + SizeType(0.1 * n); if (PsimagLite::norm(maxValue) < 1e-6) maxValue = 1.0; if (seed == 0) seed = 3443331; // create a random matrix: Random48 random(seed); SparseMatrixType sparse(n, n); Vector::Type seenThisColumn(n); SizeType counter = 0; for (SizeType i = 0; i < n; i++) { sparse.setRow(i, counter); // random vector: SizeType x = 1 + SizeType(random() * maxCol); for (SizeType j = 0; j < seenThisColumn.size(); j++) seenThisColumn[j] = false; for (SizeType j = 0; j < x; j++) { SizeType col = SizeType(random() * n); if (seenThisColumn[col]) continue; seenThisColumn[col] = true; ComplexOrRealType val = random() * maxValue; sparse.pushValue(val); sparse.pushCol(col); counter++; } } sparse.setRow(n, counter); sparse.checkValidity(); // symmetrize: SparseMatrixType sparse2; transposeConjugate(sparse2, sparse); sparse += sparse2; sparse.checkValidity(); assert(isHermitian(sparse)); // sparse solver setup ParametersForSolverType params; params.lotaMemory = lotaMemory; LanczosSolverType lanczosSolver(sparse, params); DavidsonSolverType davisonSolver(sparse, params); SparseSolverType* solver = 0; // select solver if (useDavidson) solver = &davisonSolver; else solver = &lanczosSolver; // diagonalize matrix RealType gsEnergy = 0; VectorType gsVector(n); VectorType initial(n); PsimagLite::fillRandom(initial); solver->computeOneState(gsEnergy, gsVector, initial, 0); std::cout << "Energy=" << gsEnergy << "\n"; } PsimagLite-3.06/drivers/sumDecomposition.cpp000066400000000000000000000011351446452427400212370ustar00rootroot00000000000000#include "SumDecomposition.h" int main(int argc, char* argv[]) { if (argc < 3) return 1; int total = atoi(argv[1]); int sum = atoi(argv[2]); int selection = (argc > 3) ? atoi(argv[3]) : 0; PsimagLite::SumDecomposition::SelEnum sel = PsimagLite::SumDecomposition::SEL_ALL; if (selection < 0) sel = PsimagLite::SumDecomposition::SEL_SIZE; if (selection >= 0 && argc > 3) sel = PsimagLite::SumDecomposition::SEL_INDEX; PsimagLite::SumDecomposition sd(total, sum, sel, selection); if (sel != PsimagLite::SumDecomposition::SEL_SIZE) std::cout << sd; else std::cout << sd.size() << "\n"; } PsimagLite-3.06/drivers/svd.cpp000066400000000000000000000011611446452427400164710ustar00rootroot00000000000000#include "Svd.h" #include "Matrix.h" #include "Vector.h" int main() { typedef PsimagLite::Matrix MatrixType; MatrixType a(4, 2); a(0, 0) = 2; a(0, 1) = 4; a(1, 0) = 1; a(1, 1) = 3; std::cout << "A\n"; std::cout << a; MatrixType m(a); PsimagLite::Vector::Type s; MatrixType vt; PsimagLite::Svd svd; svd('A', a, s, vt); std::cout << "U\n"; std::cout << a; std::cout << "S\n"; std::cout << s; std::cout << "\n\nFallback\n"; PsimagLite::Svd svdFallback("gesvd"); svdFallback('A', m, s, vt); std::cout << "U\n"; std::cout << m; std::cout << "S\n"; std::cout << s; } PsimagLite-3.06/drivers/testCRSMatrix.cpp000066400000000000000000000045751446452427400204250ustar00rootroot00000000000000// #include "CrsMatrix.h" #include "CrsMatrix.h" #include #include using namespace PsimagLite; typedef double RealType; template std::ostream& operator<<(std::ostream& os, const typename Vector::Type& v) { os << v.size() << "\n"; for (SizeType i = 0; i < v.size(); i++) os << v[i] << " "; os << "\n"; return os; } void fillRandomVector(Vector::Type& x, SizeType maxValue) { unsigned int long seed = 7334211; srand48(seed); for (SizeType i = 0; i < x.size(); i++) x[i] = drand48() * maxValue; } void fillRandomVector(Vector::Type& x, RealType maxValue) { unsigned int long seed = 7334211; srand48(seed); for (SizeType i = 0; i < x.size(); i++) x[i] = drand48() * maxValue; } template void testMultiply(const CrsMatrix& m, RealType maxValue) { typename Vector::Type x(m.rows(), 0.0), y(m.rows()); fillRandomVector(y, maxValue); std::cout << "initial vector:\n"; std::cout << y; m.matrixVectorProduct(x, y); std::cout << "final vector:\n"; std::cout << x; } template CrsMatrix createRandomCrs(SizeType rank, SizeType seed, SizeType nonZeros, T maxValue) { typename Vector::Type rows; typename Vector::Type cols; typename Vector::Type vals; srand48(seed); for (SizeType i = 0; i < nonZeros; ++i) { // pick a row const SizeType row = SizeType(drand48() * rank); // and a column const SizeType col = SizeType(drand48() * rank); // and a value const T val = drand48() * maxValue; rows.push_back(row); cols.push_back(col); vals.push_back(val); } // fill the matrix with this data: return CrsMatrix(rank, rows, cols, vals); } int main(int argc, char* argv[]) { if (argc == 3) { SizeType rank = std::atoi(argv[1]); unsigned int long seed = 343981; RealType ratio = std::atof(argv[2]); SizeType nonZeros = SizeType(ratio * rank * rank); RealType maxValue = 10.0; CrsMatrix m = createRandomCrs(rank, seed, nonZeros, maxValue); std::cout << m; testMultiply(m, maxValue); } else if (argc == 2) { std::ifstream fin(argv[1]); Matrix mdense(fin); fin.close(); std::cout << mdense; CrsMatrix m(mdense); RealType maxValue = 10.0; testMultiply(m, maxValue); std::cout << m; std::cout << "----------\n"; std::cout << m.toDense(); } else { throw RuntimeError("Wrong number of arguments\n"); } } PsimagLite-3.06/drivers/testExcitedLanczos.cpp000066400000000000000000000032621446452427400215200ustar00rootroot00000000000000#include "CrsMatrix.h" #include "LanczosSolver.h" #include "Matrix.h" #include "Random48.h" // <--- is this thread safe? int main(int argc, char* argv[]) { typedef double RealType; typedef std::complex ComplexType; typedef PsimagLite::ParametersForSolver SolverParametersType; typedef PsimagLite::Vector::Type VectorComplexType; typedef PsimagLite::Vector::Type VectorRealType; if (argc != 2) { std::cout << "USAGE: " << argv[0] << " excited\n"; return 1; } SizeType excited = atoi(argv[1]); SizeType n = 4; PsimagLite::Matrix m(n, n); // fill m m(1, 2) = -0.5; m(2, 1) = PsimagLite::conj(m(1, 2)); m(0, 0) = m(3, 3) = -0.25; m(1, 1) = m(2, 2) = 0.25; std::cout << "matrix\n" << m << "\n"; PsimagLite::CrsMatrix msparse(m); SolverParametersType params; params.lotaMemory = true; params.tolerance = -1; params.options = "reortho"; PsimagLite::LanczosSolver, VectorComplexType> lanczosSolver(msparse, params); PsimagLite::Random48 myrng(time(0)); VectorComplexType initialV(n, 0.0); for (SizeType i = 0; i < n; ++i) initialV[i] = myrng() - 0.5; double e1 = 0; VectorComplexType z1(n, 0.0); lanczosSolver.computeOneState(e1, z1, initialV, excited); std::cout << "energy1=" << e1 << "\n"; std::cout << z1 << "\n"; VectorRealType eigs(m.rows()); PsimagLite::diag(m, eigs, 'V'); for (SizeType i = 0; i < m.rows(); i++) { std::cerr << "eigs[" << i << "]=" << eigs[i] << "\n"; } VectorRealType zeig(n, 0.0); for (SizeType i = 0; i < m.rows(); i++) { zeig[i] = PsimagLite::real(m(i, 0)); } std::cout << m << "\n"; } PsimagLite-3.06/drivers/testGemmR.cpp000066400000000000000000000105041446452427400176050ustar00rootroot00000000000000#include "GemmR.h" #include "Matrix.h" #include typedef std::complex zcomplex; template T make_val(double const x, double const y) { return (x); } template <> double make_val(double const x, double const y) { return (x); } template <> zcomplex make_val(double const x, double const y) { zcomplex z(x, y); return (z); } template int test_GEMMR(int const Mmax, int const Nmax, int const Kmax, int const nb, bool needsPrinting) { int const idebug = (needsPrinting) ? 1 : 0; int nerrors = 0; char const trans_table[3] = { 'N', 'T', 'C' }; T const alpha = make_val(1.1, 2.1); T const beta = make_val(3.1, 4.1); PsimagLite::GemmR gemmR( needsPrinting, nb, PsimagLite::Concurrency::codeSectionParams.npthreads); for (int k = 1; k <= Kmax; k += nb) { for (int n = 1; n <= Nmax; n += nb) { for (int m = 1; m <= Mmax; m += nb) { for (int itransB = 0; itransB < 3; itransB++) { for (int itransA = 0; itransA < 3; itransA++) { char const transA = trans_table[itransA]; char const transB = trans_table[itransB]; bool const is_transA = (transA == 'T') || (transA == 't'); bool const is_transB = (transB == 'T') || (transB == 't'); bool const is_conjA = (transA == 'C') || (transA == 'c'); bool const is_conjB = (transB == 'C') || (transB == 'c'); bool const is_notransA = (!is_transA) && (!is_conjA); bool const is_notransB = (!is_transB) && (!is_conjB); int const mC = m; int const nC = n; int const mA = (is_notransA) ? mC : k; int const nA = (is_notransA) ? k : mC; int const mB = (is_notransB) ? k : nC; int const nB = (is_notransB) ? nC : k; PsimagLite::Matrix C(mC, nC); PsimagLite::Matrix C_gemmr(mC, nC); PsimagLite::Matrix A(mA, nA); PsimagLite::Matrix B(mB, nB); int const ldA = mA; int const ldB = mB; int const ldC = mC; for (int j = 0; j < nC; j++) { for (int i = 0; i < mC; i++) { T cij = make_val(1.0 * (i + j) / (mC + nC), 1.0 * i * j / (mC * nC)); C(i, j) = cij; C_gemmr(i, j) = cij; } } for (int j = 0; j < nA; j++) { for (int i = 0; i < mA; i++) { T aij = make_val(-1.0 * (i + j + 1), 1.0 * (j - i + 1)); A(i, j) = aij; } } for (int j = 0; j < nB; j++) { for (int i = 0; i < mB; i++) { T bij = make_val(1.0 * (i + j + 1) / (mB * nB), -1.0 * (j - i + 1) / (mB * nB)); B(i, j) = bij; } } gemmR(transA, transB, m, n, k, alpha, &(A(0, 0)), ldA, &(B(0, 0)), ldB, beta, &(C_gemmr(0, 0)), ldC); psimag::BLAS::GEMM(transA, transB, m, n, k, alpha, &(A(0, 0)), ldA, &(B(0, 0)), ldB, beta, &(C(0, 0)), ldC); double max_err = 0; double c_norm = 0; for (int j = 0; j < nC; j++) { for (int i = 0; i < mC; i++) { double const err = std::abs(C(i, j) - C_gemmr(i, j)); max_err = std::max(max_err, err); c_norm += std::abs(C(i, j)); } } double const tol = 0.0000001; bool const isok = (max_err < tol); if (!isok) { nerrors++; } if ((!isok) || (idebug >= 1)) { std::cout << " transA " << transA << " transB " << transB << " m " << m << " n " << n << " k " << k << " max_err " << max_err << " c_norm " << c_norm << "\n"; } } } } } } return (nerrors); } int main(int argc, char** argv) { int const Nmax = 300; int const Mmax = 301; int const Kmax = 302; int nerr_zcomplex = 0; if (argc < 2) throw PsimagLite::RuntimeError("USAGE: " + PsimagLite::String(argv[0]) + " nthreads [nb] [debug]\n"); int nthreads = atoi(argv[1]); int const nb = (argc >= 3) ? atoi(argv[2]) : 99; const bool needsPrinting = (argc == 4) ? atoi(argv[3]) > 0 : false; PsimagLite::Concurrency concurrency(&argc, &argv, nthreads); int nerr_double = test_GEMMR(Mmax, Nmax, Kmax, nb, needsPrinting); if (nerr_double == 0) { nerr_zcomplex = test_GEMMR(Mmax, Nmax, Kmax, nb, needsPrinting); } bool const all_passed = (nerr_double == 0) && (nerr_zcomplex == 0); if (all_passed) { std::cout << "ALL PASSED " << "\n"; } else { std::cout << " nerr_double = " << nerr_double << " nerr_zcomplex = " << nerr_zcomplex << "\n"; } } PsimagLite-3.06/drivers/testGemmR2.cpp000066400000000000000000000043751446452427400177000ustar00rootroot00000000000000#include "BLAS.h" #include "GemmR.h" #include "Matrix.h" #include "Parallelizer2.h" #include "Random48.h" typedef double RealType; template void fillRandom(PsimagLite::Matrix& m, RealType min, RealType max, SomeRngType& rng) { const SizeType rows = m.rows(); const SizeType cols = m.cols(); for (SizeType i = 0; i < rows; ++i) for (SizeType j = 0; j < cols; ++j) m(i, j) = min + rng() * max; } bool equalMatrices(PsimagLite::Matrix& a, PsimagLite::Matrix& b, RealType tolerance) { const SizeType rows = a.rows(); const SizeType cols = b.cols(); if (rows != b.rows() || cols != b.cols()) return false; for (SizeType i = 0; i < rows; ++i) for (SizeType j = 0; j < cols; ++j) if (fabs(a(i, j) - b(i, j)) > tolerance) return false; return true; } int main(int argc, char** argv) { if (argc < 2) throw PsimagLite::RuntimeError("USAGE: " + PsimagLite::String(argv[0]) + " total nthreadsOuter nthreadsInner\n"); const bool needsPrinting = false; int const nb = 99; int total = atoi(argv[1]); int nthreadsOuter = atoi(argv[2]); int nthreadsInner = atoi(argv[3]); PsimagLite::Concurrency concurrency(&argc, &argv, nthreadsInner); PsimagLite::Random48 rng(1234); auto lambda = [&rng, nthreadsInner](SizeType, SizeType) { PsimagLite::GemmR gemmR(needsPrinting, nb, nthreadsInner); SizeType lda = static_cast(rng() * 500) + 10; SizeType cda = lda; SizeType ldb = lda; SizeType cdb = lda; SizeType ldc = lda; SizeType cdc = lda; PsimagLite::Matrix A(lda, cda); PsimagLite::Matrix B(ldb, cdb); PsimagLite::Matrix C(ldc, cdc); fillRandom(A, -10, 10, rng); fillRandom(B, -10, 10, rng); gemmR('N', 'N', ldc, cdc, cda, 1.0, &A(0, 0), lda, &B(0, 0), ldb, 0.0, &C(0, 0), ldc); PsimagLite::Matrix C2(ldc, cdc); psimag::BLAS::GEMM('N', 'N', ldc, cdc, cda, 1.0, &A(0, 0), lda, &B(0, 0), ldb, 0.0, &C2(0, 0), ldc); if (!equalMatrices(C, C2, 1e-6)) throw PsimagLite::RuntimeError("TEST FAILED\n"); }; PsimagLite::CodeSectionParams csp = PsimagLite::Concurrency::codeSectionParams; csp.npthreads = nthreadsOuter; PsimagLite::Parallelizer2<> parallelizer2(csp); parallelizer2.parallelFor(0, total, lambda); } PsimagLite-3.06/drivers/testInput.ain000066400000000000000000000000761446452427400176650ustar00rootroot00000000000000##Ainur1.0 myscalar=3; myvector=[1,2,3,4]; mystring="Hello"; PsimagLite-3.06/drivers/testInputNg.cpp000066400000000000000000000134621446452427400201700ustar00rootroot00000000000000/* PSIDOC InputNg_Intro \section{Lesson I: InputNg} In this lesson we'll learn how to read a properly formatted input file. This way when you write your own C++ programs you'll have an already available way to read parameters from an input file and use them in your program. You can go ahead an compile this example with \begin{tiny} \begin{verbatim} g++ testInputNg.cpp -std=c++11 -Wall -I ../src/ -I.. -DUSE_BOOST -L ../lib -lpsimaglite -o testInputNg \end{verbatim} \end{tiny} Note that you need boost-dev or boost-devel and also you must have lib/libsimaglite.a already compiled. You can already go ahead an run it with the provided simple input \begin{verbatim} ./testInputNg testInput.ain \end{verbatim} What does this program do? It reads two or three ``labels'' from testInput.ain and prints some of them to the terminal. The labels have the form \texttt{label=value}, and we have a scalar, a vector, and a string as examples. So, now let's discuss the short program we have here. First, note that we need two includes from PsimagLite. PsimagLite files are usually under src, but in some cases subdirectories are used. Here are the includes. \begin{lstlisting} PSIDOC_CONTINUE */ #include "InputCheckBase.h" #include "InputNg.h" /* PSIDOC_RESUME \end{lstlisting} InputNg has an option to check the inputs, so that you can define the labels that you expect to find in your program. This is optional but recommended. For this we create a class, say \texttt{MyInputCheck}, and derive it from PsimagLite's \texttt{InputCheckBase}. This inheritance isn't needed, but save us from having to provide all functions, as the base class implements defaults. For a more realistic use case you can check DMRG++'s InputCheck.h under dmrgpp/src/Engine. For now, here's our short input checking class. \begin{lstlisting} PSIDOCCOPY InputNg_Class_MyInputCheck \end{lstlisting} In our example, we are defining a scalar called myscalar, a vector called myvector, and a string called mystring. This is what we expect to read from the input file, even though the writer of the input may add other labels. */ /* PSIDOC_CODE_START InputNg_Class_MyInputCheck nocapture */ class MyInputCheck : public PsimagLite::InputCheckBase { public: std::string import() const { std::string str("integer myscalar;\n"); str += "vector myvector;\n"; str += "string mystring;\n"; return str; } }; /* PSIDOC_CODE_END */ /* PSIDOC InputNg_main1 Now for the actual reading of the input file, we'll use \cppFile{InputNg}. We'll alias its type first with \begin{verbatim} typedef PsimagLite::InputNg InputNgType; \end{verbatim} InputNg expects one template argument, our input checking class, which we have just described. We'll also have to use the actual name provided to this program, which should be in \verb!argv[1]!, which we put in C++ variable \texttt{filename}. We need to create an object of our class MyInputCheck as well. We then have the following code so far \begin{lstlisting} PSIDOC_CONTINUE */ int main(int argc, char* argv[]) { if (argc != 2) { std::cerr << "USAGE " << argv[0] << " filename\n"; return 1; } typedef PsimagLite::InputNg InputNgType; std::string filename(argv[1]); MyInputCheck myInputCheck; /* PSIDOC_RESUME \end{lstlisting} We are now ready to read the file, which we do with the following two statements \begin{lstlisting} PSIDOC_CONTINUE */ InputNgType::Writeable ioWriteable(filename, myInputCheck); InputNgType::Readable io(ioWriteable); /* PSIDOC_RESUME \end{lstlisting} From now on, we can forget about the myInputCheck object, and the ioWriteable object as well, and consider only the io object, which we will use to read labels. The data from the file is now in memory, and the file does not have to be read or even present anymore. Let's now read some data from the file using the io object. (The data is now in memory, and it is \emph{not actually} read from the file, but we will use that terminology anyway.) We read the scalar first, and print it to the terminal with the following code. \begin{lstlisting} PSIDOC_CONTINUE */ int myscalar = 0; io.readline(myscalar, "myscalar="); std::cout << "I've read label myscalar with value "; std::cout << myscalar << " from " << io.filename() << "\n"; /* PSIDOC_RESUME \end{lstlisting} The first argument to io.readline will be filled with the value from the file that follows the label myscalar. Even though the value will be filled, it's best practice to initialize it first anyway. Let's now read a vector. Note that we use just io.read to read vectors (and matrices), whereas we use io.readline to read scalars. The vector will be resized for you as needed, so you do not need to size it. If you choose to size it, then Ainur format will be able to use ellipsis to fill the vector and you may be able to enter in the input file something like myvector=[42, ...]; which will cause your vector to be filled with the number 42. \begin{lstlisting} PSIDOC_CONTINUE */ std::vector v; io.read(v, "myvector"); /* PSIDOC_RESUME \end{lstlisting} The two previous examples required the labels to be present in the input file. But what if we want to have an \emph{optional} label in the input file? To deal with that we put the io.readline statement inside a try and catch block, as follows. \begin{lstlisting} PSIDOCCOPY InputNg_code_main5 \end{lstlisting} This way if the user provides the label mystring then the C++ variable mystr will have the value the user provided. Otherwise, the value of mystr will remain ``default'', and no error will be issued. */ /* PSIDOC_CODE_START InputNg_code_main5 nocapture */ std::string mystr("default"); try { io.readline(mystr, "mystring="); } catch (std::exception&) { } } /* PSIDOC_CODE_END */ /* PSIDOC InputNg_Recap \subsection*{Recap} In this lesson we have learned, blah blah. */ PsimagLite-3.06/drivers/testIoNg.cpp000066400000000000000000000005551446452427400174370ustar00rootroot00000000000000#include "Io/IoNg.h" void test1() { PsimagLite::IoNg::Out ioOut("hello.hdf5", PsimagLite::IoNg::ACC_TRUNC); std::vector v(10, 42.0); ioOut.write(v, "MyVector"); ioOut.close(); sleep(1); PsimagLite::IoNg::In ioIn("hello.hdf5"); std::vector w; ioIn.read(w, "MyVector"); std::cout << w; } int main(int argc, char** argv) { test1(); } PsimagLite-3.06/drivers/testIoNgBoolean.cpp000066400000000000000000000023111446452427400207270ustar00rootroot00000000000000#include "Io/IoNg.h" void createVector(std::vector& v) { SizeType n = v.size(); for (SizeType i = 0; i < n; ++i) v[i] = (drand48() < 0.5); } void saveAll(PsimagLite::String filename, const std::vector& v1, PsimagLite::String vname1, const std::vector& v2, PsimagLite::String vname2) { PsimagLite::IoNg::Out io(filename, PsimagLite::IoNg::ACC_TRUNC); io.write(v1, vname1); io.write(v2, vname2); } void compare(const std::vector& v, const std::vector& w) { SizeType n = v.size(); if (n != w.size()) std::cerr << "DIFFER on SIZE!!!\n"; for (SizeType i = 0; i < n; ++i) { if (v[i] == w[i]) continue; std::cerr << "DIFFER!!!\n"; } std::cerr << "OK\n"; } int main(int argc, char** argv) { if (argc < 2) return 1; SizeType n = atoi(argv[1]); std::vector v1(n, false); createVector(v1); std::vector v2(n, false); createVector(v2); PsimagLite::String filename = "file.hd5"; PsimagLite::String vname1 = "myv1"; PsimagLite::String vname2 = "myv2"; saveAll(filename, v1, vname1, v2, vname2); std::vector w1; std::vector w2; PsimagLite::IoNg::In io(filename); io.read(w1, vname1); io.read(w2, vname2); compare(v1, w1); compare(v2, w2); } PsimagLite-3.06/drivers/testIsClass.cpp000066400000000000000000000005751446452427400201460ustar00rootroot00000000000000#include "IsClass.h" #include class A { }; template int testIsClass() { return PsimagLite::IsClass::value; } int main() { std::cout << testIsClass() << "\n"; std::cout << testIsClass() << "\n"; std::cout << testIsClass() << "\n"; std::cout << testIsClass>() << "\n"; std::cout << testIsClass() << "\n"; } PsimagLite-3.06/drivers/testLanczos.cpp000066400000000000000000000016751446452427400202200ustar00rootroot00000000000000#include "CrsMatrix.h" #include "LanczosSolver.h" #include "Matrix.h" #include "PsimagLite.h" int main() { typedef std::complex ComplexType; typedef PsimagLite::ParametersForSolver SolverParametersType; typedef PsimagLite::Vector::Type VectorType; int n = 8; PsimagLite::Matrix m(n, n); // fill m for (int i = 0; i < n; ++i) m(i, i) = 1.0; m(1, 2) = ComplexType(0.0, 0.5); m(2, 1) = PsimagLite::conj(m(1, 2)); m(3, 5) = m(5, 3) = -1.5; PsimagLite::CrsMatrix msparse(m); SolverParametersType params; params.lotaMemory = true; PsimagLite::LanczosSolver, VectorType> lanczosSolver(msparse, params); double e = 0; VectorType z(n, 0.0); VectorType initial(n); PsimagLite::fillRandom(initial); lanczosSolver.computeOneState(e, z, initial, 0); std::cout << "energy=" << e << "\n"; std::cout << z << "\n"; } PsimagLite-3.06/drivers/testLanczosMatrixInFile.cpp000066400000000000000000000035261446452427400224710ustar00rootroot00000000000000#include "CrsMatrix.h" #include "LanczosSolver.h" #include "Matrix.h" #include "PsimagLite.h" #include int main(int argc, char** argv) { if (argc != 2) { std::cerr << "Expected filename\n"; return 1; } typedef double RealType; typedef std::complex ComplexType; typedef PsimagLite::ParametersForSolver SolverParametersType; typedef PsimagLite::Vector::Type VectorRealType; typedef PsimagLite::Vector::Type VectorType; PsimagLite::Matrix m; std::ifstream fin(argv[1]); PsimagLite::String file(argv[1]); if (!fin || fin.bad() || !fin.good()) throw PsimagLite::RuntimeError("Could not open file " + file + "\n"); SizeType tmp = 0; fin >> tmp; SizeType n = 1; fin >> n; if (tmp != n) throw PsimagLite::RuntimeError("Matrix in file " + file + " is not square\n"); m.resize(n, n, 0); for (SizeType i = 0; i < n; ++i) for (SizeType j = 0; j < n; ++j) fin >> m(i, j); PsimagLite::CrsMatrix msparse(m); SolverParametersType params; params.lotaMemory = true; params.tolerance = -1; params.options = "reortho"; typedef PsimagLite::LanczosSolver< SolverParametersType, PsimagLite::CrsMatrix, VectorType> LanczosSolverType; LanczosSolverType lanczosSolver(msparse, params); VectorType initial(n); PsimagLite::fillRandom(initial); VectorRealType eigs(n); PsimagLite::diag(m, eigs, 'V'); std::cout << "\nEXACT: "; for (SizeType excited = 0; excited < n; ++excited) std::cout << eigs[excited] << " "; std::cout << "\n"; std::cout << "LANCZ: "; LanczosSolverType::VectorVectorType zz; lanczosSolver.computeAllStatesBelow(eigs, zz, initial, n); std::cout << "LANCZOS: \n"; for (SizeType excited = 0; excited < n; ++excited) { std::cout << "_" << excited << " = " << eigs[excited] << " \n"; } std::cout << "\n"; } PsimagLite-3.06/drivers/testLapack.cpp000066400000000000000000000020471446452427400177740ustar00rootroot00000000000000#include "Vector.h" #include #include extern "C" void dsyev_(char*, char*, int*, double*, int*, double*, double*, int*, int*); int main() { int n = 100; PsimagLite::Vector::Type m(n * n); // fill "matrix" for (SizeType i = 0; i < SizeType(n * n); i++) m[i] = 5 * drand48(); // symmetrize: for (SizeType i = 0; i < SizeType(n); i++) for (SizeType j = i + 1; j < SizeType(n); j++) m[i + j * n] = m[j + i * n]; PsimagLite::Vector::Type eigs(n); char jobz = 'V'; char uplo = 'U'; int lda = n; PsimagLite::Vector::Type work(3); int info = 0; int lwork = -1; // query: dsyev_(&jobz, &uplo, &n, &(m[0]), &lda, &(eigs[0]), &(work[0]), &lwork, &info); if (info != 0) { std::cerr << "diag: dsyev_: failed with info=" << info << "\n"; return 1; } lwork = int(work[0]) + 1; work.resize(lwork + 1); // real work: dsyev_(&jobz, &uplo, &n, &(m[0]), &lda, &(eigs[0]), &(work[0]), &lwork, &info); if (info != 0) { std::cerr << "diag: dsyev_: failed with info=" << info << "\n"; return 1; } } PsimagLite-3.06/drivers/testParallelSvd.cpp000066400000000000000000000032521446452427400210110ustar00rootroot00000000000000#include "BLAS.h" #include "GemmR.h" #include "Matrix.h" #include "Random48.h" #include "Svd.h" typedef double RealType; template void fillRandom(PsimagLite::Matrix& m, RealType min, RealType max, SomeRngType& rng) { const SizeType rows = m.rows(); const SizeType cols = m.cols(); for (SizeType i = 0; i < rows; ++i) for (SizeType j = 0; j < cols; ++j) m(i, j) = min + rng() * max; } bool equalMatrices(PsimagLite::Matrix& a, PsimagLite::Matrix& b, RealType tolerance) { const SizeType rows = a.rows(); const SizeType cols = b.cols(); if (rows != b.rows() || cols != b.cols()) return false; for (SizeType i = 0; i < rows; ++i) for (SizeType j = 0; j < cols; ++j) if (fabs(a(i, j) - b(i, j)) > tolerance) return false; return true; } int main(int argc, char** argv) { if (argc < 2) throw PsimagLite::RuntimeError("USAGE: " + PsimagLite::String(argv[0]) + " total nthreadsOuter\n"); int total = atoi(argv[1]); int nthreadsOuter = atoi(argv[2]); PsimagLite::Concurrency concurrency(&argc, &argv, nthreadsOuter); PsimagLite::Random48 rng(1234); auto lambda = [&rng](SizeType, SizeType) { SizeType lda = static_cast(rng() * 500) + 10; SizeType cda = lda; PsimagLite::Matrix A(lda, cda); fillRandom(A, -10, 10, rng); PsimagLite::Svd svd; PsimagLite::Vector::Type s(lda); PsimagLite::Matrix vt; svd('A', A, s, vt); }; PsimagLite::CodeSectionParams csp = PsimagLite::Concurrency::codeSectionParams; csp.npthreads = nthreadsOuter; PsimagLite::Parallelizer2<> parallelizer2(csp); parallelizer2.parallelFor(0, total, lambda); } PsimagLite-3.06/drivers/testParallelizer2.cpp000066400000000000000000000012131446452427400213030ustar00rootroot00000000000000#include "LoadBalancerWeights.h" #include "Parallelizer2.h" #include "Vector.h" int main(int argc, char** argv) { if (argc < 3) return 1; const SizeType n = atoi(argv[1]); const SizeType threads = atoi(argv[2]); PsimagLite::Vector::Type v(n); PsimagLite::Parallelizer2<> parallelizer(threads); std::cout << "Testing Parallelizer2 with " << parallelizer.name(); std::cout << " and " << parallelizer.numberOfThreads() << " threads.\n"; parallelizer.parallelFor(0, n, [&v](SizeType i, SizeType) { v[i] = i + 42; }); /* for (SizeType i = 0; i < n; ++i) { v[i] = i + 42; } */ std::cout << v[0] << " " << v[n - 1] << "\n"; } PsimagLite-3.06/drivers/testPredicate.cpp000066400000000000000000000004601446452427400204760ustar00rootroot00000000000000#include "PredicateAwesome.h" #include int main(int argc, char** argv) { if (argc < 3) return 1; PsimagLite::String predicate(argv[1]); PsimagLite::replaceAll(predicate, "c", "5"); PsimagLite::PredicateAwesome<> pAwesome(predicate); std::cout << pAwesome.isTrue("l", atoi(argv[2])); } PsimagLite-3.06/drivers/threads.cpp000066400000000000000000000036071446452427400173360ustar00rootroot00000000000000/* Copyright (c) 2009-2017, UT-Battelle, LLC All rights reserved [PsimagLite, Version 1.] ********************************************************* THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. Please see full open source license included in file LICENSE. ********************************************************* */ #include "Concurrency.h" #include #include #define USE_PTHREADS_OR_NOT_NG #include "Parallelizer.h" class MyHelper { typedef PsimagLite::Concurrency ConcurrencyType; typedef PsimagLite::Vector::Type VectorSizeType; public: MyHelper(SizeType ntasks, SizeType nthreads) : ntasks_(ntasks) , x_(nthreads, 0) { } SizeType tasks() const { return ntasks_; } int result() const { return x_[0]; } void doTask(SizeType taskNumber, SizeType threadNum) { x_[threadNum] += taskNumber; } void sync() { for (SizeType i = 1; i < x_.size(); ++i) x_[0] += x_[i]; } private: SizeType ntasks_; VectorSizeType x_; }; // class MyHelper int main(int argc, char* argv[]) { typedef PsimagLite::Concurrency ConcurrencyType; if (argc != 3) { std::cout << "USAGE: " << argv[0] << " nthreads ntasks\n"; return 1; } SizeType nthreads = atoi(argv[1]); SizeType ntasks = atoi(argv[2]); ConcurrencyType concurrency(&argc, &argv, nthreads); typedef MyHelper HelperType; typedef PsimagLite::Parallelizer ParallelizerType; ParallelizerType threadObject(ConcurrencyType::codeSectionParams); HelperType helper(ntasks, nthreads); std::cout << "Using " << threadObject.name(); std::cout << " with " << nthreads << " threads.\n"; threadObject.loopCreate(helper); helper.sync(); std::cout << "Sum of all tasks= " << helper.result() << "\n"; } PsimagLite-3.06/lib/000077500000000000000000000000001446452427400142625ustar00rootroot00000000000000PsimagLite-3.06/lib/configure.pl000077500000000000000000000056361446452427400166150ustar00rootroot00000000000000#!/usr/bin/perl =pod Copyright (c) 2009-2015, UT-Battelle, LLC All rights reserved [PsimagLite, Version 1.0] ********************************************************* THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. Please see full open source license included in file LICENSE. ********************************************************* =cut use warnings; use strict; use Getopt::Long qw(:config no_ignore_case); use lib "../scripts"; use NewMake; use PsiTag; my @drivers = (); my ($flavor, $config) = ("production", ""); my $usage = "USAGE: $0 [-f flavor] [-c config]\n"; GetOptions('f=s' => \$flavor, 'c=s' => \$config) or die "$usage\n"; my @configFiles = ("../TestSuite/inputs/ConfigBase.psiTag"); push @configFiles, $config if ($config ne ""); createMakefile(\@configFiles, $flavor); sub createMakefile { my ($configFiles, $flavor) = @_; NewMake::backupMakefile(); my $fh; open($fh, ">", "Makefile") or die "Cannot open Makefile for writing: $!\n"; local *FH = $fh; my @units = ("MersenneTwister","Matrix","Mpi","Concurrency", "ProgressIndicator","MemResolv","PsimagLite","PsiBase64", "SpecialFunctions", "Io/TypeToH5", "TridiagonalMatrix", "PredicateSimple"); my $combinedUnits = combine("",\@units,".o "); my $combinedUnitsModif = $combinedUnits; $combinedUnitsModif =~ s/Io\///; my $combinedUnits2 = combine("../src/",\@units,".cpp "); my $configContent = NewMake::getConfigContent($configFiles, $flavor); print FH< Makefile.dep clean: Makefile.dep \trm -f core* *.o *.dep *.a include Makefile.dep EOF close($fh); print STDERR "File Makefile has been written\n"; } sub combine { my ($pre,$a,$post) = @_; my $n = scalar(@$a); my $buffer = ""; for (my $i = 0; $i < $n; ++$i) { $buffer .= $pre.$a->[$i].$post; } return $buffer; } PsimagLite-3.06/lib/newconfigure.pl000077500000000000000000000011541446452427400173160ustar00rootroot00000000000000#!/usr/bin/perl =pod Copyright (c) 2009-2018, UT-Battelle, LLC All rights reserved [DMRG++, Version 5.] ********************************************************* THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. Please see full open source license included in file LICENSE. ********************************************************* =cut use warnings; use strict; die "$0: Please use configure.pl instead of this program\n"; PsimagLite-3.06/lib/nohdf5.psitag000066400000000000000000000001031446452427400166500ustar00rootroot00000000000000 dependency HDF5 = ( ) addto basics = CPPFLAGS += -DUSE_IO_SIMPLE PsimagLite-3.06/loki/000077500000000000000000000000001446452427400144525ustar00rootroot00000000000000PsimagLite-3.06/loki/NullType.h000066400000000000000000000025411446452427400164010ustar00rootroot00000000000000//////////////////////////////////////////////////////////////////////////////// // The Loki Library // Copyright (c) 2001 by Andrei Alexandrescu // This code accompanies the book: // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design // Patterns Applied". Copyright (c) 2001. Addison-Wesley. // Permission to use, copy, modify, distribute and sell this software for any // purpose is hereby granted without fee, provided that the above copyright // notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. // The author or Addison-Wesley Longman make no representations about the // suitability of this software for any purpose. It is provided "as is" // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// #ifndef LOKI_NULLTYPE_INC_ #define LOKI_NULLTYPE_INC_ // $Id: NullType.h 751 2006-10-17 19:50:37Z syntheticpp $ namespace Loki { //////////////////////////////////////////////////////////////////////////////// // class NullType // Used as a placeholder for "no type here" // Useful as an end marker in typelists //////////////////////////////////////////////////////////////////////////////// class NullType {}; } // namespace Loki #endif // end file guardian PsimagLite-3.06/loki/Sequence.h000066400000000000000000000033031446452427400163720ustar00rootroot00000000000000//////////////////////////////////////////////////////////////////////////////// // The Loki Library // Copyright (c) 2005 by Peter K\"mmel // Permission to use, copy, modify, distribute and sell this software for any // purpose is hereby granted without fee, provided that the above copyright // notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. // The author makes no representations about the // suitability of this software for any purpose. It is provided "as is" // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// #ifndef LOKI_SEQUENCE_INC_ #define LOKI_SEQUENCE_INC_ // $Id: Sequence.h 768 2006-10-25 20:40:40Z syntheticpp $ #include "Typelist.h" namespace Loki { template < class T01=NullType,class T02=NullType,class T03=NullType,class T04=NullType,class T05=NullType, class T06=NullType,class T07=NullType,class T08=NullType,class T09=NullType,class T10=NullType, class T11=NullType,class T12=NullType,class T13=NullType,class T14=NullType,class T15=NullType, class T16=NullType,class T17=NullType,class T18=NullType,class T19=NullType,class T20=NullType > struct Seq { private: typedef typename Seq< T02, T03, T04, T05, T06, T07, T08, T09, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>::Type TailResult; public: typedef Typelist Type; }; template<> struct Seq<> { typedef NullType Type; }; } // namespace Loki #endif // end file guardian PsimagLite-3.06/loki/TypeManip.h000066400000000000000000000234761446452427400165450ustar00rootroot00000000000000//////////////////////////////////////////////////////////////////////////////// // The Loki Library // Copyright (c) 2001 by Andrei Alexandrescu // This code accompanies the book: // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design // Patterns Applied". Copyright (c) 2001. Addison-Wesley. // Permission to use, copy, modify, distribute and sell this software for any // purpose is hereby granted without fee, provided that the above copyright // notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. // The author or Addison-Welsey Longman make no representations about the // suitability of this software for any purpose. It is provided "as is" // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// #ifndef LOKI_TYPEMANIP_INC_ #define LOKI_TYPEMANIP_INC_ // $Id: TypeManip.h 749 2006-10-17 19:49:26Z syntheticpp $ namespace Loki { //////////////////////////////////////////////////////////////////////////////// // class template Int2Type // Converts each integral constant into a unique type // Invocation: Int2Type where v is a compile-time constant integral // Defines 'value', an enum that evaluates to v //////////////////////////////////////////////////////////////////////////////// template struct Int2Type { enum { value = v }; }; //////////////////////////////////////////////////////////////////////////////// // class template Type2Type // Converts each type into a unique, insipid type // Invocation Type2Type where T is a type // Defines the type OriginalType which maps back to T //////////////////////////////////////////////////////////////////////////////// template struct Type2Type { typedef T OriginalType; }; //////////////////////////////////////////////////////////////////////////////// // class template Select // Selects one of two types based upon a boolean constant // Invocation: Select::Result // where: // flag is a compile-time boolean constant // T and U are types // Result evaluates to T if flag is true, and to U otherwise. //////////////////////////////////////////////////////////////////////////////// template struct Select { typedef T Result; }; template struct Select { typedef U Result; }; //////////////////////////////////////////////////////////////////////////////// // class template IsSameType // Return true iff two given types are the same // Invocation: SameType::value // where: // T and U are types // Result evaluates to true iff U == T (types equal) //////////////////////////////////////////////////////////////////////////////// template struct IsSameType { enum { value = false }; }; template struct IsSameType { enum { value = true }; }; //////////////////////////////////////////////////////////////////////////////// // Helper types Small and Big - guarantee that sizeof(Small) < sizeof(Big) //////////////////////////////////////////////////////////////////////////////// namespace Private { template struct ConversionHelper { typedef char Small; struct Big { char dummy[2]; }; static Big Test(...); static Small Test(U); static T MakeT(); }; } //////////////////////////////////////////////////////////////////////////////// // class template Conversion // Figures out the conversion relationships between two types // Invocations (T and U are types): // a) Conversion::exists // returns (at compile time) true if there is an implicit conversion from T // to U (example: Derived to Base) // b) Conversion::exists2Way // returns (at compile time) true if there are both conversions from T // to U and from U to T (example: int to char and back) // c) Conversion::sameType // returns (at compile time) true if T and U represent the same type // // Caveat: might not work if T and U are in a private inheritance hierarchy. //////////////////////////////////////////////////////////////////////////////// template struct Conversion { typedef Private::ConversionHelper H; #ifndef __MWERKS__ enum { exists = sizeof(typename H::Small) == sizeof((H::Test(H::MakeT()))) }; #else enum { exists = false }; #endif enum { exists2Way = exists && Conversion::exists }; enum { sameType = false }; }; template struct Conversion { enum { exists = 1, exists2Way = 1, sameType = 1 }; }; template struct Conversion { enum { exists = 0, exists2Way = 0, sameType = 0 }; }; template struct Conversion { enum { exists = 0, exists2Way = 0, sameType = 0 }; }; template <> struct Conversion { public: enum { exists = 1, exists2Way = 1, sameType = 1 }; }; //////////////////////////////////////////////////////////////////////////////// // class template SuperSubclass // Invocation: SuperSubclass::value where B and D are types. // Returns true if B is a public base of D, or if B and D are aliases of the // same type. // // Caveat: might not work if T and U are in a private inheritance hierarchy. //////////////////////////////////////////////////////////////////////////////// template struct SuperSubclass { enum { value = (::Loki::Conversion::exists && !::Loki::Conversion::sameType) }; // Dummy enum to make sure that both classes are fully defined. enum{ dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) }; }; template <> struct SuperSubclass { enum { value = false }; }; template struct SuperSubclass { enum { value = (::Loki::Conversion::exists && !::Loki::Conversion::sameType) }; // Dummy enum to make sure that both classes are fully defined. enum{ dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) }; }; template struct SuperSubclass { enum { value = (::Loki::Conversion::exists && !::Loki::Conversion::sameType) }; // Dummy enum to make sure that both classes are fully defined. enum{ dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) }; }; //////////////////////////////////////////////////////////////////////////////// // class template SuperSubclassStrict // Invocation: SuperSubclassStrict::value where B and D are types. // Returns true if B is a public base of D. // // Caveat: might not work if T and U are in a private inheritance hierarchy. //////////////////////////////////////////////////////////////////////////////// template struct SuperSubclassStrict { enum { value = (::Loki::Conversion::exists && !::Loki::Conversion::sameType && !::Loki::Conversion::sameType) }; // Dummy enum to make sure that both classes are fully defined. enum{ dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) }; }; template<> struct SuperSubclassStrict { enum { value = false }; }; template struct SuperSubclassStrict { enum { value = (::Loki::Conversion::exists && !::Loki::Conversion::sameType && !::Loki::Conversion::sameType) }; // Dummy enum to make sure that both classes are fully defined. enum{ dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) }; }; template struct SuperSubclassStrict { enum { value = (::Loki::Conversion::exists && !::Loki::Conversion::sameType && !::Loki::Conversion::sameType) }; // Dummy enum to make sure that both classes are fully defined. enum{ dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) }; }; } // namespace Loki //////////////////////////////////////////////////////////////////////////////// // macro SUPERSUBCLASS // Invocation: SUPERSUBCLASS(B, D) where B and D are types. // Returns true if B is a public base of D, or if B and D are aliases of the // same type. // // Caveat: might not work if T and U are in a private inheritance hierarchy. // Deprecated: Use SuperSubclass class template instead. //////////////////////////////////////////////////////////////////////////////// #define LOKI_SUPERSUBCLASS(T, U) \ ::Loki::SuperSubclass::value //////////////////////////////////////////////////////////////////////////////// // macro SUPERSUBCLASS_STRICT // Invocation: SUPERSUBCLASS(B, D) where B and D are types. // Returns true if B is a public base of D. // // Caveat: might not work if T and U are in a private inheritance hierarchy. // Deprecated: Use SuperSubclassStrict class template instead. //////////////////////////////////////////////////////////////////////////////// #define LOKI_SUPERSUBCLASS_STRICT(T, U) \ ::Loki::SuperSubclassStrict::value #endif // end file guardian PsimagLite-3.06/loki/TypeTraits.h000066400000000000000000002677311446452427400167530ustar00rootroot00000000000000//////////////////////////////////////////////////////////////////////////////// // The Loki Library // Copyright (c) 2001 by Andrei Alexandrescu // This code accompanies the book: // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design // Patterns Applied". Copyright (c) 2001. Addison-Wesley. // Permission to use, copy, modify, distribute and sell this software for any // purpose is hereby granted without fee, provided that the above copyright // notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. // The author or Addison-Wesley Longman make no representations about the // suitability of this software for any purpose. It is provided "as is" // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// #ifndef LOKI_TYPETRAITS_INC_ #define LOKI_TYPETRAITS_INC_ // $Id: TypeTraits.h 835 2007-08-02 19:39:02Z syntheticpp $ #include "Typelist.h" #include "Sequence.h" #if (defined _MSC_VER) && (_MSC_VER < 1400) #include #endif #ifdef _MSC_VER #pragma warning( push ) #pragma warning( disable : 4180 ) //qualifier applied to function type has no meaning; ignored #endif namespace Loki { //////////////////////////////////////////////////////////////////////////////// // class template IsCustomUnsignedInt // Offers a means to integrate nonstandard built-in unsigned integral types // (such as unsigned __int64 or unsigned long long int) with the TypeTraits // class template defined below. // Invocation: IsCustomUnsignedInt where T is any type // Defines 'value', an enum that is 1 iff T is a custom built-in unsigned // integral type // Specialize this class template for nonstandard unsigned integral types // and define value = 1 in those specializations //////////////////////////////////////////////////////////////////////////////// template struct IsCustomUnsignedInt { enum { value = 0 }; }; //////////////////////////////////////////////////////////////////////////////// // class template IsCustomSignedInt // Offers a means to integrate nonstandard built-in unsigned integral types // (such as unsigned __int64 or unsigned long long int) with the TypeTraits // class template defined below. // Invocation: IsCustomSignedInt where T is any type // Defines 'value', an enum that is 1 iff T is a custom built-in signed // integral type // Specialize this class template for nonstandard unsigned integral types // and define value = 1 in those specializations //////////////////////////////////////////////////////////////////////////////// template struct IsCustomSignedInt { enum { value = 0 }; }; //////////////////////////////////////////////////////////////////////////////// // class template IsCustomFloat // Offers a means to integrate nonstandard floating point types with the // TypeTraits class template defined below. // Invocation: IsCustomFloat where T is any type // Defines 'value', an enum that is 1 iff T is a custom built-in // floating point type // Specialize this class template for nonstandard unsigned integral types // and define value = 1 in those specializations //////////////////////////////////////////////////////////////////////////////// template struct IsCustomFloat { enum { value = 0 }; }; //////////////////////////////////////////////////////////////////////////////// // Helper types for class template TypeTraits defined below //////////////////////////////////////////////////////////////////////////////// namespace Private { #ifndef LOKI_DISABLE_TYPELIST_MACROS typedef LOKI_TYPELIST_4(unsigned char, unsigned short int,unsigned int, unsigned long int) StdUnsignedInts; typedef LOKI_TYPELIST_4(signed char, short int,int, long int) StdSignedInts; typedef LOKI_TYPELIST_3(bool, char, wchar_t) StdOtherInts; typedef LOKI_TYPELIST_3(float, double, long double) StdFloats; #else typedef Loki::Seq::Type StdUnsignedInts; typedef Loki::Seq::Type StdSignedInts; typedef Loki::Seq::Type StdOtherInts; typedef Loki::Seq::Type StdFloats; #endif template struct AddPointer { typedef U* Result; }; template struct AddPointer { typedef U* Result; }; template struct AddReference { typedef U & Result; }; template struct AddReference { typedef U & Result; }; template <> struct AddReference { typedef NullType Result; }; template struct AddParameterType { typedef const U & Result; }; template struct AddParameterType { typedef U & Result; }; template <> struct AddParameterType { typedef NullType Result; }; template struct IsFunctionPointerRaw {enum{result = 0};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum{result = 0};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; // Const versions template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; // Volatile versions template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; // Const volatile versions template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; template struct IsMemberFunctionPointerRaw {enum {result = 1};}; }// namespace Private //////////////////////////////////////////////////////////////////////////////// // class template TypeTraits // // Figures out at compile time various properties of any given type // Invocations (T is a type, TypeTraits::Property): // // - isPointer : returns true if T is a pointer type // - PointeeType : returns the type to which T points if T is a pointer // type, NullType otherwise // - isReference : returns true if T is a reference type // - ReferredType : returns the type to which T refers if T is a reference // type, NullType otherwise // - isMemberPointer : returns true if T is a pointer to member type // - isStdUnsignedInt: returns true if T is a standard unsigned integral type // - isStdSignedInt : returns true if T is a standard signed integral type // - isStdIntegral : returns true if T is a standard integral type // - isStdFloat : returns true if T is a standard floating-point type // - isStdArith : returns true if T is a standard arithmetic type // - isStdFundamental: returns true if T is a standard fundamental type // - isUnsignedInt : returns true if T is a unsigned integral type // - isSignedInt : returns true if T is a signed integral type // - isIntegral : returns true if T is a integral type // - isFloat : returns true if T is a floating-point type // - isArith : returns true if T is a arithmetic type // - isFundamental : returns true if T is a fundamental type // - ParameterType : returns the optimal type to be used as a parameter for // functions that take Ts // - isConst : returns true if T is a const-qualified type // - NonConstType : Type with removed 'const' qualifier from T, if any // - isVolatile : returns true if T is a volatile-qualified type // - NonVolatileType : Type with removed 'volatile' qualifier from T, if any // - UnqualifiedType : Type with removed 'const' and 'volatile' qualifiers from // T, if any // - ParameterType : returns the optimal type to be used as a parameter // for functions that take 'const T's // //////////////////////////////////////////////////////////////////////////////// template class TypeTraits { private: template struct ReferenceTraits { enum { result = false }; typedef U ReferredType; }; template struct ReferenceTraits { enum { result = true }; typedef U ReferredType; }; template struct PointerTraits { enum { result = false }; typedef NullType PointeeType; }; template struct PointerTraits { enum { result = true }; typedef U PointeeType; }; template struct PointerTraits { enum { result = true }; typedef U PointeeType; }; template struct PToMTraits { enum { result = false }; }; template struct PToMTraits { enum { result = true }; }; template struct PToMTraits { enum { result = true }; }; template struct FunctionPointerTraits { enum{ result = Private::IsFunctionPointerRaw::result }; }; template struct PToMFunctionTraits { enum{ result = Private::IsMemberFunctionPointerRaw::result }; }; template struct UnConst { typedef U Result; enum { isConst = 0 }; }; template struct UnConst { typedef U Result; enum { isConst = 1 }; }; template struct UnConst { typedef U& Result; enum { isConst = 1 }; }; template struct UnVolatile { typedef U Result; enum { isVolatile = 0 }; }; template struct UnVolatile { typedef U Result; enum { isVolatile = 1 }; }; template struct UnVolatile { typedef U& Result; enum { isVolatile = 1 }; }; public: typedef typename UnConst::Result NonConstType; typedef typename UnVolatile::Result NonVolatileType; typedef typename UnVolatile::Result>::Result UnqualifiedType; typedef typename PointerTraits::PointeeType PointeeType; typedef typename ReferenceTraits::ReferredType ReferredType; enum { isConst = UnConst::isConst }; enum { isVolatile = UnVolatile::isVolatile }; enum { isReference = ReferenceTraits::result }; enum { isFunction = FunctionPointerTraits::Result >::result }; enum { isFunctionPointer= FunctionPointerTraits< typename ReferenceTraits::ReferredType >::result }; enum { isMemberFunctionPointer= PToMFunctionTraits< typename ReferenceTraits::ReferredType >::result }; enum { isMemberPointer = PToMTraits< typename ReferenceTraits::ReferredType >::result || isMemberFunctionPointer }; enum { isPointer = PointerTraits< typename ReferenceTraits::ReferredType >::result || isFunctionPointer }; enum { isStdUnsignedInt = TL::IndexOf::value >= 0 || TL::IndexOf::ReferredType>::value >= 0}; enum { isStdSignedInt = TL::IndexOf::value >= 0 || TL::IndexOf::ReferredType>::value >= 0}; enum { isStdIntegral = isStdUnsignedInt || isStdSignedInt || TL::IndexOf::value >= 0 || TL::IndexOf::ReferredType>::value >= 0}; enum { isStdFloat = TL::IndexOf::value >= 0 || TL::IndexOf::ReferredType>::value >= 0}; enum { isStdArith = isStdIntegral || isStdFloat }; enum { isStdFundamental = isStdArith || isStdFloat || Conversion::sameType }; enum { isUnsignedInt = isStdUnsignedInt || IsCustomUnsignedInt::value }; enum { isSignedInt = isStdSignedInt || IsCustomSignedInt::value }; enum { isIntegral = isStdIntegral || isUnsignedInt || isSignedInt }; enum { isFloat = isStdFloat || IsCustomFloat::value }; enum { isArith = isIntegral || isFloat }; enum { isFundamental = isStdFundamental || isArith }; typedef typename Select::Result>::Result ParameterType; }; } #ifdef _MSC_VER #pragma warning( pop ) #endif // _MSC_VER #endif // end file guardian PsimagLite-3.06/loki/Typelist.h000066400000000000000000000373041446452427400164470ustar00rootroot00000000000000//////////////////////////////////////////////////////////////////////////////// // The Loki Library // Copyright (c) 2001 by Andrei Alexandrescu // This code accompanies the book: // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design // Patterns Applied". Copyright (c) 2001. Addison-Wesley. // Permission to use, copy, modify, distribute and sell this software for any // purpose is hereby granted without fee, provided that the above copyright // notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. // The author or Addison-Welsey Longman make no representations about the // suitability of this software for any purpose. It is provided "as is" // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// #ifndef LOKI_TYPELIST_INC_ #define LOKI_TYPELIST_INC_ // $Id: Typelist.h 749 2006-10-17 19:49:26Z syntheticpp $ #include "NullType.h" #include "TypeManip.h" #include "TypelistMacros.h" namespace Loki { //////////////////////////////////////////////////////////////////////////////// // class template Typelist // The building block of typelists of any length // Use it through the LOKI_TYPELIST_NN macros // Defines nested types: // Head (first element, a non-typelist type by convention) // Tail (second element, can be another typelist) //////////////////////////////////////////////////////////////////////////////// template struct Typelist { typedef T Head; typedef U Tail; }; // Typelist utility algorithms namespace TL { //////////////////////////////////////////////////////////////////////////////// // class template MakeTypelist // Takes a number of arguments equal to its numeric suffix // The arguments are type names. // MakeTypelist::Result // returns a typelist that is of T1, T2, ... //////////////////////////////////////////////////////////////////////////////// template < typename T1 = NullType, typename T2 = NullType, typename T3 = NullType, typename T4 = NullType, typename T5 = NullType, typename T6 = NullType, typename T7 = NullType, typename T8 = NullType, typename T9 = NullType, typename T10 = NullType, typename T11 = NullType, typename T12 = NullType, typename T13 = NullType, typename T14 = NullType, typename T15 = NullType, typename T16 = NullType, typename T17 = NullType, typename T18 = NullType > struct MakeTypelist { private: typedef typename MakeTypelist < T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10, T11, T12, T13, T14, T15, T16, T17, T18 > ::Result TailResult; public: typedef Typelist Result; }; template<> struct MakeTypelist<> { typedef NullType Result; }; //////////////////////////////////////////////////////////////////////////////// // class template Length // Computes the length of a typelist // Invocation (TList is a typelist): // Length::value // returns a compile-time constant containing the length of TList, not counting // the end terminator (which by convention is NullType) //////////////////////////////////////////////////////////////////////////////// template struct Length; template <> struct Length { enum { value = 0 }; }; template struct Length< Typelist > { enum { value = 1 + Length::value }; }; //////////////////////////////////////////////////////////////////////////////// // class template TypeAt // Finds the type at a given index in a typelist // Invocation (TList is a typelist and index is a compile-time integral // constant): // TypeAt::Result // returns the type in position 'index' in TList // If you pass an out-of-bounds index, the result is a compile-time error //////////////////////////////////////////////////////////////////////////////// template struct TypeAt; template struct TypeAt, 0> { typedef Head Result; }; template struct TypeAt, i> { typedef typename TypeAt::Result Result; }; //////////////////////////////////////////////////////////////////////////////// // class template TypeAtNonStrict // Finds the type at a given index in a typelist // Invocations (TList is a typelist and index is a compile-time integral // constant): // a) TypeAt::Result // returns the type in position 'index' in TList, or NullType if index is // out-of-bounds // b) TypeAt::Result // returns the type in position 'index' in TList, or D if index is out-of-bounds //////////////////////////////////////////////////////////////////////////////// template struct TypeAtNonStrict { typedef DefaultType Result; }; template struct TypeAtNonStrict, 0, DefaultType> { typedef Head Result; }; template struct TypeAtNonStrict, i, DefaultType> { typedef typename TypeAtNonStrict::Result Result; }; //////////////////////////////////////////////////////////////////////////////// // class template IndexOf // Finds the index of a type in a typelist // Invocation (TList is a typelist and T is a type): // IndexOf::value // returns the position of T in TList, or NullType if T is not found in TList //////////////////////////////////////////////////////////////////////////////// template struct IndexOf; template struct IndexOf { enum { value = -1 }; }; template struct IndexOf, T> { enum { value = 0 }; }; template struct IndexOf, T> { private: enum { temp = IndexOf::value }; public: enum { value = (temp == -1 ? -1 : 1 + temp) }; }; //////////////////////////////////////////////////////////////////////////////// // class template Append // Appends a type or a typelist to another // Invocation (TList is a typelist and T is either a type or a typelist): // Append::Result // returns a typelist that is TList followed by T and NullType-terminated //////////////////////////////////////////////////////////////////////////////// template struct Append; template <> struct Append { typedef NullType Result; }; template struct Append { typedef Typelist Result; }; template struct Append > { typedef Typelist Result; }; template struct Append, T> { typedef Typelist::Result> Result; }; //////////////////////////////////////////////////////////////////////////////// // class template Erase // Erases the first occurence, if any, of a type in a typelist // Invocation (TList is a typelist and T is a type): // Erase::Result // returns a typelist that is TList without the first occurence of T //////////////////////////////////////////////////////////////////////////////// template struct Erase; template // Specialization 1 struct Erase { typedef NullType Result; }; template // Specialization 2 struct Erase, T> { typedef Tail Result; }; template // Specialization 3 struct Erase, T> { typedef Typelist::Result> Result; }; //////////////////////////////////////////////////////////////////////////////// // class template EraseAll // Erases all first occurences, if any, of a type in a typelist // Invocation (TList is a typelist and T is a type): // EraseAll::Result // returns a typelist that is TList without any occurence of T //////////////////////////////////////////////////////////////////////////////// template struct EraseAll; template struct EraseAll { typedef NullType Result; }; template struct EraseAll, T> { // Go all the way down the list removing the type typedef typename EraseAll::Result Result; }; template struct EraseAll, T> { // Go all the way down the list removing the type typedef Typelist::Result> Result; }; //////////////////////////////////////////////////////////////////////////////// // class template NoDuplicates // Removes all duplicate types in a typelist // Invocation (TList is a typelist): // NoDuplicates::Result //////////////////////////////////////////////////////////////////////////////// template struct NoDuplicates; template <> struct NoDuplicates { typedef NullType Result; }; template struct NoDuplicates< Typelist > { private: typedef typename NoDuplicates::Result L1; typedef typename Erase::Result L2; public: typedef Typelist Result; }; //////////////////////////////////////////////////////////////////////////////// // class template Replace // Replaces the first occurence of a type in a typelist, with another type // Invocation (TList is a typelist, T, U are types): // Replace::Result // returns a typelist in which the first occurence of T is replaced with U //////////////////////////////////////////////////////////////////////////////// template struct Replace; template struct Replace { typedef NullType Result; }; template struct Replace, T, U> { typedef Typelist Result; }; template struct Replace, T, U> { typedef Typelist::Result> Result; }; //////////////////////////////////////////////////////////////////////////////// // class template ReplaceAll // Replaces all occurences of a type in a typelist, with another type // Invocation (TList is a typelist, T, U are types): // Replace::Result // returns a typelist in which all occurences of T is replaced with U //////////////////////////////////////////////////////////////////////////////// template struct ReplaceAll; template struct ReplaceAll { typedef NullType Result; }; template struct ReplaceAll, T, U> { typedef Typelist::Result> Result; }; template struct ReplaceAll, T, U> { typedef Typelist::Result> Result; }; //////////////////////////////////////////////////////////////////////////////// // class template Reverse // Reverses a typelist // Invocation (TList is a typelist): // Reverse::Result // returns a typelist that is TList reversed //////////////////////////////////////////////////////////////////////////////// template struct Reverse; template <> struct Reverse { typedef NullType Result; }; template struct Reverse< Typelist > { typedef typename Append< typename Reverse::Result, Head>::Result Result; }; //////////////////////////////////////////////////////////////////////////////// // class template MostDerived // Finds the type in a typelist that is the most derived from a given type // Invocation (TList is a typelist, T is a type): // MostDerived::Result // returns the type in TList that's the most derived from T //////////////////////////////////////////////////////////////////////////////// template struct MostDerived; template struct MostDerived { typedef T Result; }; template struct MostDerived, T> { private: typedef typename MostDerived::Result Candidate; public: typedef typename Select< SuperSubclass::value, Head, Candidate>::Result Result; }; //////////////////////////////////////////////////////////////////////////////// // class template DerivedToFront // Arranges the types in a typelist so that the most derived types appear first // Invocation (TList is a typelist): // DerivedToFront::Result // returns the reordered TList //////////////////////////////////////////////////////////////////////////////// template struct DerivedToFront; template <> struct DerivedToFront { typedef NullType Result; }; template struct DerivedToFront< Typelist > { private: typedef typename MostDerived::Result TheMostDerived; typedef typename Replace::Result Temp; typedef typename DerivedToFront::Result L; public: typedef Typelist Result; }; } // namespace TL } // namespace Loki #endif // end file guardian PsimagLite-3.06/loki/TypelistMacros.h000066400000000000000000000443711446452427400176160ustar00rootroot00000000000000//////////////////////////////////////////////////////////////////////////////// // The Loki Library // Copyright (c) 2001 by Andrei Alexandrescu // This code accompanies the book: // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design // Patterns Applied". Copyright (c) 2001. Addison-Wesley. // Permission to use, copy, modify, distribute and sell this software for any // purpose is hereby granted without fee, provided that the above copyright // notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. // The author or Addison-Welsey Longman make no representations about the // suitability of this software for any purpose. It is provided "as is" // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// #ifndef LOKI_TYPELISTMACROS_INC_ #define LOKI_TYPELISTMACROS_INC_ // $Id: TypelistMacros.h 749 2006-10-17 19:49:26Z syntheticpp $ //#define LOKI_DISABLE_TYPELIST_MACROS #ifndef LOKI_DISABLE_TYPELIST_MACROS //////////////////////////////////////////////////////////////////////////////// // macros LOKI_TYPELIST_1, LOKI_TYPELIST_2, ... LOKI_TYPELIST_50 // Each takes a number of arguments equal to its numeric suffix // The arguments are type names. LOKI_TYPELIST_NN generates a typelist containing // all types passed as arguments, in that order. // Example: LOKI_TYPELIST_2(char, int) generates a type containing char and int. //////////////////////////////////////////////////////////////////////////////// #define LOKI_TYPELIST_1(T1) ::Loki::Typelist #define LOKI_TYPELIST_2(T1, T2) ::Loki::Typelist #define LOKI_TYPELIST_3(T1, T2, T3) ::Loki::Typelist #define LOKI_TYPELIST_4(T1, T2, T3, T4) \ ::Loki::Typelist #define LOKI_TYPELIST_5(T1, T2, T3, T4, T5) \ ::Loki::Typelist #define LOKI_TYPELIST_6(T1, T2, T3, T4, T5, T6) \ ::Loki::Typelist #define LOKI_TYPELIST_7(T1, T2, T3, T4, T5, T6, T7) \ ::Loki::Typelist #define LOKI_TYPELIST_8(T1, T2, T3, T4, T5, T6, T7, T8) \ ::Loki::Typelist #define LOKI_TYPELIST_9(T1, T2, T3, T4, T5, T6, T7, T8, T9) \ ::Loki::Typelist #define LOKI_TYPELIST_10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) \ ::Loki::Typelist #define LOKI_TYPELIST_11(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) \ ::Loki::Typelist #define LOKI_TYPELIST_12(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) \ ::Loki::Typelist #define LOKI_TYPELIST_13(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) \ ::Loki::Typelist #define LOKI_TYPELIST_14(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14) \ ::Loki::Typelist #define LOKI_TYPELIST_15(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15) \ ::Loki::Typelist #define LOKI_TYPELIST_16(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16) \ ::Loki::Typelist #define LOKI_TYPELIST_17(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17) \ ::Loki::Typelist #define LOKI_TYPELIST_18(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18) \ ::Loki::Typelist #define LOKI_TYPELIST_19(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19) \ ::Loki::Typelist #define LOKI_TYPELIST_20(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) \ ::Loki::Typelist #define LOKI_TYPELIST_21(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) \ ::Loki::Typelist #define LOKI_TYPELIST_22(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) \ ::Loki::Typelist #define LOKI_TYPELIST_23(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23) \ ::Loki::Typelist #define LOKI_TYPELIST_24(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24) \ ::Loki::Typelist #define LOKI_TYPELIST_25(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25) \ ::Loki::Typelist #define LOKI_TYPELIST_26(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26) \ ::Loki::Typelist #define LOKI_TYPELIST_27(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27) \ ::Loki::Typelist #define LOKI_TYPELIST_28(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28) \ ::Loki::Typelist #define LOKI_TYPELIST_29(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29) \ ::Loki::Typelist #define LOKI_TYPELIST_30(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30) \ ::Loki::Typelist #define LOKI_TYPELIST_31(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31) \ ::Loki::Typelist #define LOKI_TYPELIST_32(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32) \ ::Loki::Typelist #define LOKI_TYPELIST_33(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33) \ ::Loki::Typelist #define LOKI_TYPELIST_34(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33, T34) \ ::Loki::Typelist #define LOKI_TYPELIST_35(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35) \ ::Loki::Typelist #define LOKI_TYPELIST_36(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36) \ ::Loki::Typelist #define LOKI_TYPELIST_37(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37) \ ::Loki::Typelist #define LOKI_TYPELIST_38(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38) \ ::Loki::Typelist #define LOKI_TYPELIST_39(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39) \ ::Loki::Typelist #define LOKI_TYPELIST_40(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40) \ ::Loki::Typelist #define LOKI_TYPELIST_41(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41) \ ::Loki::Typelist #define LOKI_TYPELIST_42(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42) \ ::Loki::Typelist #define LOKI_TYPELIST_43(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43) \ ::Loki::Typelist #define LOKI_TYPELIST_44(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44) \ ::Loki::Typelist #define LOKI_TYPELIST_45(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ T41, T42, T43, T44, T45) \ ::Loki::Typelist #define LOKI_TYPELIST_46(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ T41, T42, T43, T44, T45, T46) \ ::Loki::Typelist #define LOKI_TYPELIST_47(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ T41, T42, T43, T44, T45, T46, T47) \ ::Loki::Typelist #define LOKI_TYPELIST_48(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ T41, T42, T43, T44, T45, T46, T47, T48) \ ::Loki::Typelist #define LOKI_TYPELIST_49(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ T41, T42, T43, T44, T45, T46, T47, T48, T49) \ ::Loki::Typelist #define LOKI_TYPELIST_50(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ T41, T42, T43, T44, T45, T46, T47, T48, T49, T50) \ ::Loki::Typelist #endif //LOKI_DISABLE_TYPELIST_MACROS #endif // end file guardian PsimagLite-3.06/scripts/000077500000000000000000000000001446452427400152035ustar00rootroot00000000000000PsimagLite-3.06/scripts/Batch.pl000077500000000000000000000026351446452427400165720ustar00rootroot00000000000000#!/usr/bin/perl #PBS -N mpi #PBS -q batch #PBS -l nodes=2:ppn=16 #PBS -l walltime=1:00:00 #PBS -l vmem=90gb use strict; use warnings; use utf8; chdir $ENV{"PBS_O_WORKDIR"}; #date my $np=4; my $nodefile = $ENV{"PBS_NODEFILE"}; my $h = getHostString($nodefile, $np); #my $realCmd = "hostname"; my $realCmd = "./internode 4"; my $command = "LD_LIBRARY_PATH=\${LD_LIBRARY_PATH}:/usr/lib64/openmpi/lib "; $command .= "/usr/lib64/openmpi/bin/mpiexec -n $np -host \"$h\" $realCmd"; system("$command"); sub getHostString { my ($file, $mpiJobs) = @_; my %h; my $firstNode; open(FILE, "<", "$file") or die "$0: Cannot open $file : $!\n"; while () { chomp; next if (/^#/ or $_ eq ""); my $f = $_; $firstNode = $f; if (!defined($h{"$f"})) { $h{"$f"} = 1; } else { ++$h{"$f"}; } } close(FILE); my $nodes = scalar(keys %h); die "$0: Nodes $nodes must be a multiple of mpiJobs $mpiJobs\n" if ($mpiJobs % $nodes != 0); die "$0: No nodes!\n" if ($nodes == 0 or !defined($firstNode)); my $ppn = $h{"$firstNode"}; my $repeat = $mpiJobs/$nodes; return getHostString2($repeat, \%h); } sub getHostString2 { my ($repeat, $h) = @_; my $firstcall = 1; my $str = ""; for (my $i = 0; $i < $repeat; ++$i) { foreach my $key (sort keys %$h) { my $n = $h->{"$key"}; next if ($n == 0); if ($firstcall) { $firstcall = 0; } else { $str .= ","; } $str .= "$key"; } } return $str; } PsimagLite-3.06/scripts/FunctionParsing.pm000066400000000000000000000076411446452427400206620ustar00rootroot00000000000000#!/usr/bin/perl -w use warnings; use strict; package FunctionParsing; my $multiLineComment = 0; my $buffer=""; my $pristineBuffer=""; sub getNextFunction { my ($ffunc,$fh,$doNotPrint)=@_; while(<$fh>) { my $savedLine = $_; s/\/\*.*\*\///; s/\/\/.*$//; $multiLineComment = 1 if (/^[\t ]*\/\*/); if ($multiLineComment) { print $savedLine unless ($doNotPrint); $multiLineComment = 0 if (/\*\//); next; } # Empty lines: my $line = $_; $line=~s/[ \t]+//; $line=~s/\n//; $pristineBuffer .= $savedLine; if ($line eq "") { print $pristineBuffer unless ($doNotPrint); $pristineBuffer=""; next; } # Buffer $buffer .= $_; if (/\{/) { my $needsPrinting = procBuffer(\$ffunc,$buffer,$doNotPrint); print $pristineBuffer if ($needsPrinting and !$doNotPrint); $buffer=""; $pristineBuffer=""; next if ($needsPrinting); next unless ($doNotPrint); my %ggg = %$ffunc; # print STDERR "******".$ggg{"name"}."\n"; return if ($doNotPrint); } if (/\}[ \t]*$/ || /\:[ \t]*$/ || /\;[ \t]*$/) { $buffer = "" ; print $pristineBuffer unless ($doNotPrint); $pristineBuffer=""; } } } sub procBuffer { my ($ffunc,$t,$doNotPrint)=@_; return 1 if ($t=~/\#define /); return 1 if ($t=~/\#include /); # Find first parens my $first=""; my $second=""; if ($t=~/(^[^\(]+)\(([^\)]*)\)/) { $first = $1; $second = $2; } return 1 if ($first eq ""); my %func = %$$ffunc; $func{"post-qualifier"} = getPostQualifier($t); getFirstPart(\%func,$first); %$$ffunc = %func; # my $name = $func{"name"}; # return 1 if (isInVector(\@keywords,$name)); # # printFunc(\%func); # # my @funcArgs=getArgs($second); # for (my $i=0;$i<=$#funcArgs;$i++) { # print STDERR " ~ $funcArgs[$i] "; # } # my $length=computeLength(\%func,\@funcArgs); # print STDERR " LENGTH=$length\n"; # print STDERR "\n-----------------------------\n"; # return 1 if ($length<$GlobalMaxLine || $#funcArgs<1); # rewriteSig(\%func,\@funcArgs) unless ($doNotPrint); return 0; } sub getFirstPart { my ($f,$first)=@_; $$f{"level"}=getLevel($first); $first=~s/\n/\@ /g; $_=$first; my @temp=split; my $n = $#temp+1; if ($n==1) { # It's a constructor or destructor $$f{"pre-qualifier"}=""; $$f{"type"}=""; $$f{"name"}=$temp[0]; return; } if ($n==2) { # unqualified function or destructor if ($temp[1]=~/^\~/) { # destructor $$f{"pre-qualifier"}=$temp[0]; $$f{"type"}=""; $$f{"name"}=$temp[1]; return; } # unqualified function $$f{"pre-qualifier"}=""; $$f{"type"}=$temp[0]; $$f{"name"}=$temp[1]; return; } # $n>2 --> qualified function $_=$first; s/[^ \t]+[\t ]*$//; # kill name s/[^ \t]+[\t ]*$//; #kill type s/^[\t ]*//; s/[\t ]*$//; $$f{"pre-qualifier"} = $_; $$f{"name"}=$temp[$n-1]; $$f{"type"}=$temp[$n-2]; } sub getPostQualifier { my ($t)=@_; my $ret = ""; $t=~s/\n/\@/g; if ($t=~/\)(.*$)/) { $ret = $1; $ret =~ s/[ \t]+$//g; } return $ret; } sub getLevel { my ($t)=@_; $_=$t; if ($t=~/\n/) { my @temp=split/\n/; $_=$temp[$#temp]; } #print STDERR "HERE $_\n"; my $counter=0; while(s/^\t//) { #print STDERR "*".$1."*\n"; $counter++; } return $counter; } sub getArgs { my ($t)=@_; return if ($t eq ""); $_ = $t; my @fa=split/,/; my $n = $#fa+1; for (my $i=0;$i<$n;$i++) { $fa[$i]=~s/^[\t ]+//; $fa[$i]=~s/[\t ]+$//; $fa[$i]=~s/[\n\r]//g; } return glueArgs(\@fa); } sub glueArgs { my ($fa)=@_; my @ret; my $buffer=""; my $openFlag=0; my $n = scalar(@$fa); my $counter=0; for (my $i=0;$i<$n;$i++) { $buffer .= "," unless ($buffer eq ""); $_ = $fa->[$i]; s/^[\t ]*//; s/[\t ]*$//; $buffer .= $_; $openFlag += countChars($fa->[$i],"<"); $openFlag -= countChars($fa->[$i],">"); if ($openFlag==0) { $ret[$counter++]=$buffer; $buffer=""; } } # $ret[$counter++]=$buffer; # $buffer=""; return @ret; } sub countChars { my ($t,$c)=@_; $_=$t; my $counter=0; while(s/\Q$c//) { $counter++; } return $counter; } 1; PsimagLite-3.06/scripts/Make.pm000077500000000000000000000146601446452427400164300ustar00rootroot00000000000000#!/usr/bin/perl =pod Copyright (c) 2009-2014, UT-Battelle, LLC All rights reserved [PsimagLite, Version 1.0.0] ********************************************************* THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. Please see full open source license included in file LICENSE. ********************************************************* =cut use warnings; use strict; use File::Temp; package Make; sub newMake { local *FH = shift; my ($drivers, $additionals) = @_; die "newMake: needs additionals as 3rd argument\n" if (!defined($additionals)); my %a = %$additionals; my $additional = $a{"additional"}; my $additional2 = $a{"additional2"}; my $additional3 = $a{"additional3"}; my $path = $a{"path"}; my $code = $a{"code"}; $additional = " " unless defined($additional); $additional2 = " " unless defined($additional2); $additional3 = "" unless defined($additional3); $path = " " unless defined($path); my $allExecutables = combineAllDrivers($drivers,""); my $allCpps = combineAllDrivers($drivers,".cpp"); print FH<{"name"}; my $aux = ($oldmode) ? 0 : $ptr->{"aux"}; $aux = 0 if (!defined($aux)); my $dotos = ($oldmode) ? "$what.o" : $ptr->{"dotos"}; $dotos = "$what.o" if (!defined($dotos)); print FH<{"libs"}; my $libs1 = ""; my $libs2 = ""; if (defined($libs) and $libs ne "") { $libs1 = "lib$libs.a"; $libs2 = "-l$libs"; } print FH< Makefile.dep clean:: rm -f core* $allExecutables *.o *.dep *.a $additional2 include Makefile.dep EOF } sub make { local *FH = shift; my ($drivers, $code, $platform, $mpi, $libs, $cxx, $cppflags, $strip, $additional, $additional2, $additional3) = @_; $additional3 = "" unless defined($additional3); my $allExecutables = combineAllDrivers($drivers,""); my $allCpps = combineAllDrivers($drivers,".cpp"); my $libTarget = ""; if ($libs=~/\-lpsimaglite/) { $libTarget = " ../../PsimagLite/lib/libpsimaglite.a"; psimagLiteLibMake(); } print FH< Makefile.dep clean: Makefile.dep rm -f core* $allExecutables *.o *.a *.dep $additional2 include Makefile.dep EOF } sub combineAllDrivers { my ($drivers,$extension) = @_; my $buffer = ""; foreach my $ptr (@$drivers) { my $refptr = ref($ptr); my $oldmode = ($refptr eq ""); my $what = ($oldmode) ? $ptr : $ptr->{"name"}; my $aux = ($oldmode) ? 0 : $ptr->{"aux"}; defined($aux) or $aux = 0; next if ($aux and $extension eq ""); my $tmp = $what.$extension." "; $buffer .= $tmp; } return $buffer; } sub psimagLiteLibMake { print STDERR "$0: Make sure to compile PsimagLite/lib first\n"; } sub backupMakefile { my ($dir) = @_; $dir = "." unless defined($dir); system("cp $dir/Makefile $dir/Makefile.bak") if (-r "$dir/Makefile"); print STDERR "$0: Backup of $dir/Makefile in $dir/Makefile.bak\n"; } sub findGsl { my $gslDefine = " -DUSE_GSL "; my $gslLibs = " -lgsl -lgslcblas "; my $slashTmp = "/tmp"; my @nothingFound = (" ", " "); return @nothingFound unless (-w $slashTmp); my $dir = File::Temp::tempdir(CLEANUP => 1); my ($fh, $filename) = File::Temp::tempfile(DIR => $dir); if (!$fh) { return @nothingFound; } print $fh </dev/null"); return ($gslDefine, $gslLibs) if (-x "a.out"); return @nothingFound; } sub createConfigMake { my ($flavor, $additionals) = @_; defined($flavor) or $flavor = "../TestSuite/inputs/Config.make"; my $cmd = "cp ../TestSuite/inputs/ConfigBase.make Config.make.new"; system($cmd); print STDERR "$0: Executed $cmd\n"; if (!(-r "$flavor")) { print STDERR "$0: WARNING: I didn't find $flavor, ignoring...\n"; return; } open(FILE, "<", $flavor) or return; if (!open(FOUT, ">>", "Config.make.new")) { close(FILE); return; } while () { next if (/ConfigBase\.make/); print FOUT; } close(FILE); if (defined($additionals)) { my $cppflags = $additionals->{"CPPFLAGS"}; my $ldflags = $additionals->{"LDFLAGS"}; print FOUT "CPPFLAGS += $cppflags\n" if ($cppflags ne ""); print FOUT "LDFLAGS += $ldflags\n" if ($ldflags ne ""); } close(FOUT); my $overwrite = 1; if (-r "Config.make") { $overwrite = 0; print "$0: Config.make exists. Do you want to overwrite it?\n"; print "$0: Your answer: (n/Y): "; $_ = ; chomp; $overwrite = ($_ eq "Y"); if (!$overwrite) { print STDERR "$0: Please consider comparing your Config.make\n"; print STDERR "\t to the one I've written to Config.make.new\n"; return; } } $cmd = "mv Config.make.new Config.make"; system($cmd); print STDERR "$0: Written Config.make\n"; } 1; PsimagLite-3.06/scripts/NewMake.pm000077500000000000000000000115241446452427400170760ustar00rootroot00000000000000#!/usr/bin/perl =pod Copyright (c) 2009-2014, UT-Battelle, LLC All rights reserved [PsimagLite, Version 1.0.0] ********************************************************* THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. Please see full open source license included in file LICENSE. ********************************************************* =cut use warnings; use strict; package NewMake; sub main { local *FH = shift; my ($args, $drivers) = @_; die "NewMake::main(): needs drivers as 3rd argument\n" if (!defined($drivers)); my %a = %$args; my $additional = $a{"additional"}; my $additional2 = $a{"additional2"}; my $additional3 = $a{"additional3"}; my $additional4 = $a{"additional4"}; my $ldflagsAdditionals = $a{"LDFLAGS"}; my $cppflagsAdditionals = $a{"CPPFLAGS"}; my $path = $a{"path"}; my $code = $a{"code"}; $additional = " " unless defined($additional); $additional2 = " " unless defined($additional2); $additional3 = "" unless defined($additional3); $additional4 = "" unless defined($additional4); $ldflagsAdditionals = "" unless defined($ldflagsAdditionals); $cppflagsAdditionals = "" unless defined($cppflagsAdditionals); $path = " " unless defined($path); my $allExecutables = combineAllDrivers($drivers,""); my $allCpps = combineAllDrivers($drivers,".cpp"); my $configContent = getConfigContent($args->{"configFiles"}, $args->{"flavor"}); print FH<{"name"}; my $aux = ($oldmode) ? 0 : $ptr->{"aux"}; $aux = 0 if (!defined($aux)); my $dotos = ($oldmode) ? "$what.o" : $ptr->{"dotos"}; $dotos = "$what.o" if (!defined($dotos)); print FH<{"libs"}; if (defined($libs) and $libs ne "") { $libs1 = "lib$libs.a"; $libs2 = "-l$libs"; } } else { my $needsPsimagLiteLib = $a{"needsPsimagLiteLib"}; if ($needsPsimagLiteLib) { $libs1 = "$path../../PsimagLite/lib/libpsimaglite.a"; $libs2 = "-lpsimaglite"; } } print FH< Makefile.dep clean:: rm -f core* $allExecutables *.o *.a *.dep $additional2 include Makefile.dep EOF } sub configFilesList { my ($basic, $optional) = @_; my @list = ($basic); if (defined($optional)) { push @list, $optional; print "$0: Info: Using @list\n"; return @list; } $optional = $ENV{"PSITAG_CONFIG_USER"}; push @list, $optional if $optional; print "$0: Info: Using @list\n"; return @list; } sub combineAllDrivers { my ($drivers,$extension) = @_; my $buffer = ""; foreach my $ptr (@$drivers) { my $refptr = ref($ptr); my $oldmode = ($refptr eq ""); my $what = ($oldmode) ? $ptr : $ptr->{"name"}; my $aux = ($oldmode) ? 0 : $ptr->{"aux"}; defined($aux) or $aux = 0; next if ($aux and $extension eq ""); my $tmp = $what.$extension." "; $buffer .= $tmp; } return $buffer; } sub backupMakefile { my ($dir) = @_; $dir = "." unless defined($dir); system("cp $dir/Makefile $dir/Makefile.bak") if (-r "$dir/Makefile"); print STDERR "$0: Backup of $dir/Makefile in $dir/Makefile.bak\n"; } sub getConfigContent { my ($files, $flavor) = @_; my %tags; my $n = scalar(@$files); for (my $i = 0; $i < $n; ++$i) { PsiTag::main(\%tags, $files->[$i]); } flavorHelp(\%tags) if ($flavor eq "help"); $flavor = PsiTag::canonicalTagName($tags{"default flavor"}->{"content"}) if ($flavor eq noFlavor()); my $ptr = $tags{"flavor $flavor"}; defined($ptr) or die "$0: No flavor named $flavor\n"; my $configContent = $ptr->{"content"}; defined($configContent) or die "$0: No configContent for tag $flavor\n"; return PsiTag::unWrap(\%tags, $configContent); } sub noFlavor { return "UNDEFINED"; } sub flavorHelp { my ($tags) = @_; print "$0: Available flavors are: "; foreach my $key (keys %$tags) { print "$1 " if ($key =~ /^flavor (.+)$/); } print "\n"; exit(1); } 1; PsimagLite-3.06/scripts/PsiScript.pl6000077500000000000000000000043241446452427400175540ustar00rootroot00000000000000#!/usr/bin/perl6 use v6; my $self = $*PROGRAM-NAME; sub MAIN(Str $name, *@args) { $name ~~ / ^<[\w .]>+ $ / or die "$self: NAME $name not alphanumeric\n"; my Str $psiPath = getPsiPath(); my $scriptsPath = $psiPath ~ "/dmrgpp/scripts"; my $command = findCommand($name, $scriptsPath); shell $command ~ " " ~ @args.join(' '); } sub findCommand(Str $name2, Str $scriptsPath) { my Str $name = $name2; my $extension = $name.IO.extension; if ($extension eq "") { my $b6 = ($name ~ ".pl6").IO ~~ :r & :x; my $b5 = ($name ~ ".pl").IO ~~ :r & :x; if ($b5 && $b6) { die "$self: Failed for $name, both $b5 $b6 v6 and v5 exist\n"; } if (!$b5 && !$b6) { die "$self: Neither $name.pl nor $name.pl6 exist\n"; } $extension = "pl" if ($b5); $extension = "pl6" if ($b6); $name ~= ".$extension" if ($extension); } die "$self: File $name with wrong extension\n" unless ($extension); return commandFromNameAndExtension($name, $extension, $scriptsPath); } sub commandFromNameAndExtension(Str $name, Str $extension, Str $scriptsPath) { die "$self: scriptsPath/$name not in git index\n" unless isInGitIndex($name, $scriptsPath); $name.IO ~~ :r & :x or die "$self: scriptsPath/$name is not read AND exec\n"; my $interpreter; $interpreter = "/usr/bin/perl6" if ($extension eq "pl6"); $interpreter = "/usr/bin/perl" if ($extension eq "pl"); die "$self: Cannot find interpreter\n" unless ($interpreter); my $argsForInterpreter = ($extension eq "pl") ?? " -I $scriptsPath " !! ""; return "$interpreter $argsForInterpreter $scriptsPath/$name "; } sub isInGitIndex(Str $name, Str $scriptsPath) { my $oldir = $*CWD.basename; chdir $scriptsPath; my $full = $scriptsPath ~ "/" ~ $name; $name ~~ / ^<[\w .]>+ $ / or die "$self: NAME $name not alphanumeric\n"; my $capture = q:x/git ls-files $full/; #q:x return $capture.trim-trailing ~~ / "$name" /; } sub getPsiPath() { my Str $homeDir = %*ENV{"HOME"}; my Str $file = $homeDir ~ "/.config/PsimagLite/config"; my $psiDir; for $file.IO.lines { next if (/^\s* "#" /); if (/"PSI_DIR" \s* "=" \s* (.+$) /) { $psiDir = $0; last; } } ($psiDir) or die "$self: Cannot find PSI_DIR in $file\n"; return ($psiDir ~~ /^ "/" /) ?? $psiDir !! $homeDir ~ "/" ~ $psiDir; } PsimagLite-3.06/scripts/PsiTag.pm000066400000000000000000000170601446452427400167340ustar00rootroot00000000000000#!/usr/bin/perl use strict; use warnings; use utf8; =pod Syntax: tagging mode content content can appear multiline if scope is block block is between ( ) multiline tagging and mode must appear in the same line Mode is either add definition and overwrite if it exits = add definition and append to it if it exits += add definition or ignore if it exits =? add definition or fail if it exits =! delete from definition or ignore if it doesn't exist -= delete from definition or fail if it exits -=! tagging must not contain any of = + ? ! - < & * Content is subject to interpretation as follows. (0) sometag = () Deletes sometag if it exits. Spaces around = are optional. Note that sometag = sets the content of sometag to nothing, and is different from deletion. (1) First non-whitespace character after mode in the same line, if it is a ( (2) Last non-whitespace character in a line, if it is a ) (3) First non-whitespace character in a line or after mode, if it is a < and what follows until newline is considered the tagging (4) First non-whitespace character in line or after mode, if it is an escape \ will be removed. This is so that the next character will not be interpreted (5) Last non-whitespace character in a line, if it is a \ will be removed. This is so that the previous character will not be interpreted Tagging is canonicalized as follows: See canonicalTagName below. Proposal for improvement: if statement after mode Example: mytag ? [if xyz] = 42 sets mytag to 42 only if xyz is an existing tag Syntax: tagging ? [ modifier ] mode content where tagging, mode, and content are treated and defined as before, modifier MUST NOT be multiline; and \[ is replaced into [ and \] into ] modifer = submodifer1 &&& submodifer2 &&& submodifer3 \&&& is replaced into &&& for each submodifer. The only submodifer type allowed for now is type if. And it is allowed only once. submodifierOfTypeIf = if predicate where predicate = subpredicate1 SEPARATOR subpredicate2 SEPARATOR ... If only one subpredicate is present SEPARATOR MUST be ommited. Separator is one of || for logical OR, and && for logical AND. For each subpredicate, \|| is replaced into || and \&& into &&. subpredicate = tag subpredicate = ! tag subpredicate = tag == content subpredicate = tag != content subpredicate = tag1 == < tag2 subpredicate = tag1 != < tag2 Spaces are optional. Spaces before and after content will be part of content. content MUST NOT be multiline; the whole predicate is within the line. =cut package PsiTag; sub main { my ($tags, $file) = @_; my @lines; readLines(\@lines, $file); my %tags; readTags($tags, \@lines); } sub readLines { my ($lines, $file) = @_; open(FILE, "<", $file) or die "$0: Cannot open $file : $!\n"; while () { chomp; push @$lines, $_; } close(FILE); } sub readTags { my ($tags, $lines) = @_; my $n = scalar(@$lines); my $blockScope = 0; my $multilineContent; my $multilineTag; my $multilineMode; my $parensBalance = 0; for (my $i = 0; $i < $n; ++$i) { my $line = $lines->[$i]; if ($line =~ /^[ \t]*\}[ \t]*$/) { print STDERR "$0: Warning Closing brace on its own in line $i\n"; } if (!$blockScope) { next if ($line =~ /^\#/ or isEmptyLine($line)); if ($line =~ /^([^\=\+\?\!\-\<\&\*]+)\=[ \t]*\(\)[ \t]*$/) { my $tag = $1; removeTag($tags, canonicalTagName($tag)); next; } if ($line =~ /^([^\=\+\?\!\-\<\&\*]+)([\=\+\?\!\-\<\&\*]+)[ \t]*(.*)$/) { my $tag = $1; my $mode = $2; my $rest = $3; my $thisLineParens = 0; if ($rest =~ s/^[ \t]*\(//) { # (1) ++$thisLineParens; ++$parensBalance; die "$0: FATAL: (line scope) Nested parens not allowed, line=$line\n" if ($parensBalance > 1); } if ($rest =~ s/\)[ \t]*$//) { # (2) in line scope --$thisLineParens; --$parensBalance; die "$0: FATAL: Closing parens but context closed already, line=$line\n" if ($parensBalance < 0); } my $content = $rest."\n"; $content =~ s/^[ \t]+//; if ($thisLineParens < 0) { print STDERR "$0: ) found but not in block scope\n"; syntaxError($line, $i + 1); } ($tag) or die "$0: FATAL: tag does not exist in line scope $line\n"; if ($thisLineParens > 0) { $blockScope = 1; $multilineContent = ""; $multilineTag = canonicalTagName($tag); $multilineMode = $mode; } else { addTag($tags, canonicalTagName($tag), $mode, $content); } } else { syntaxError($line, $i + 1); } } else { # in block scope my $content = $line."\n"; my $closeScope = 0; $content =~ s/^[ \t]+//; if ($content =~ s/\)[ \t]*$//) { # (2) in block scope $closeScope = 1; --$parensBalance; die "$0: FATAL: (block scope) Nested parens not allowed, line=$line\n" if ($parensBalance > 1); } $multilineContent .= $content; if ($closeScope) { $blockScope = 0; addTag($tags, $multilineTag, $multilineMode, $multilineContent); $multilineTag = $multilineMode = $multilineContent = ""; next; } } } } sub addTag { my ($tags, $tag, $mode, $content) = @_; # mode is # = (add or overwrite) # += (append) # -= (delete) # =? (selective add) # =! (strict add) # -=! (strict delete) # Does the tag exist? my $mytag = $tags->{"$tag"}; my $b = defined($mytag); my $oldContent = ($b) ? $tags->{"$tag"}{"content"} : ""; my $append = (($mode eq "=?" && !$b) or ($mode eq "+=") or ($mode eq "=!" && !$b) or ($mode eq "=")); die "$0: FATAL: Adding tag $tag with $mode, but $tag already exists\n" if ($mode eq "=!" && $b); return if ($mode eq "=?" && $b); if ($append) { $oldContent = "" if ($mode eq "="); $tags->{"$tag"} = {"content" => "$oldContent$content"}; return; } if ($mode eq "-=" or $mode eq "-=!") { print STDERR "$0: WARNING: Deletion of content in non-existing tag $tag\n" if (!$b); my $hasIt = ($oldContent =~ /\Q$content/); die "$0: FATAL: Strict delete of non-existing content in tag $tag\n" if ($mode eq "-=!" && !$hasIt); return if (!$hasIt); $oldContent =~ s/\Q$content//g if ($hasIt); $tags->{"$tag"} = {"content" => "$oldContent"}; return; } die "$0: FATAL: Unknown mode $mode applied to tag $tag\n"; } sub removeTag { my ($tags, $tag) = @_; defined($tags->{"$tag"}) or return; delete $tags->{"$tag"}; } sub syntaxError { my ($line, $ind) = @_; print STDERR "$0: FATAL: Syntax error line $ind\n"; die "$0: ----> $line <------\n"; } sub isEmptyLine { my ($line) = @_; $line =~ s/[ \t]//g; return ($line eq ""); } sub canonicalTagName { my ($name) = @_; $name =~ s/\n/ /g; $name =~ s/^[ \t]*//; $name =~ s/[ \t]*$//; while ($name =~ s/[ \t][ \t]/ /) {} return $name; } sub unWrap { my ($tags, $text) = @_; my @lines = split/\n/, $text; my $n = scalar(@lines); my $result = ""; for (my $i = 0; $i < $n; ++$i) { my $line = $lines[$i]; my $content = $line; if ($line =~ /^[ \t]*\<(.*$)/) { # (3) in block scope my $existingTag = $1; ($existingTag) or die "$0: FATAL: Tag does not exist in unWrap: $line\n"; $existingTag = canonicalTagName($existingTag); my $ptr = $tags->{"$existingTag"}; defined($ptr) or die "$0: FATAL: Tag $existingTag doesn't exist\n"; (ref($ptr) eq "HASH") or die "$0: FATAL: Tag $existingTag not hash ref but ".ref($ptr)."\n"; $content = $ptr->{"content"}; defined($content) or die "$0: FATAL: No content for $existingTag\n"; $content = unWrap($tags, $content); } $content =~ s/^[ \t]*\\//; # (4) $content =~ s/\\([ \t]*)$/$1/; # (5) $result .= $content."\n"; } return $result; } 1; PsimagLite-3.06/scripts/colorOutput.pl000066400000000000000000000021071446452427400200770ustar00rootroot00000000000000use Term::ANSIColor; use strict; =pod run it with: ./dmrg input507-45a.inp 2>&1 | perl ~/programs/github/PsimagLite/scripts/colorOutput.pl >& out & tail out reset the screen with: perl colorOutput.pl reset See available colors here: http://en.wikipedia.org/wiki/ANSI_escape_code =cut my ($needReset)=@ARGV; if (defined($needReset)) { print color 'reset'; exit(0); } my %colors; $colors{"WaveFunctionTransf"}='yellow'; $colors{"Truncation"}='green'; $colors{"DmrgSolver"}='red'; $colors{"LeftRightSuper"}='magenta'; $colors{"Diag."}='cyan'; $colors{"LanczosSolver"}='bold white'; #$colors{"DensityMatrixLocal"}='darkgray'; $SIG{INT}=\&myhandler; while() { chomp; procLine($_); print "\n"; } sub procLine { my ($t)=@_; print color 'reset'; if (!/\:/) { print "$t"; return; } my @temp = split/\:/,$t; #print STDERR "--$temp[0]--\n"; my $c = $colors{$temp[0]}; if (!defined($c)) { print color 'reset'; print "$t"; return; } #print STDERR " c = $c----\n"; print color "$c"; print "$t"; print color 'reset'; } sub myhandler { print color 'reset'; } PsimagLite-3.06/scripts/countLines.pl000066400000000000000000000016311446452427400176640ustar00rootroot00000000000000#!/usr/bin/perl -w use strict; use warnings; use File::Find::Rule; my ($directory)=@ARGV; defined($directory) or die "$0: USAGE: $0 directory\n"; my @files = File::Find::Rule->file()->name("*.cpp", "*.h") ->in($directory); my $counter=0; my $fileCounter = 0; foreach my $file (@files) { $counter += countThisFile($file); $fileCounter++; } print "Total Lines=$counter\n"; print "Total Files=$fileCounter\n"; sub countThisFile { my ($file)=@_; my $s=0; #my $printEach = 1000; my $multiLineComments=0; open(FILE,$file) or die "Cannot open file $file : $!\n"; while() { chomp; s/\t//g; s/ //g; next if ($_ eq ""); next if (/^\/\//); next if (/^\/\*.*\*\/$/); $multiLineComments=1 if (/^\/\*/); $multiLineComments=0 if (/\*\/$/); next if ($multiLineComments); $s++; #print "*${file}*::$_\n" if (($s % $printEach)==0); } close(FILE); return $s; } PsimagLite-3.06/scripts/doc.pl000077500000000000000000000217621446452427400163200ustar00rootroot00000000000000#!/usr/bin/perl use strict; =pod PSIDOC label PSIDOCCOPY label =cut my ($file, $doc_root, $out_dir) = @ARGV; my $find = "find ../src -iname \"*.h\" -or -iname \"*.cpp\""; defined($file) or die "USAGE: $find | $0 file\n"; my %labels; loadFiles(\%labels, $file); my @lines; loadLines(\@lines); loadLabels(\%labels, \@lines); recursiveExpand(\%labels); replaceLabels($file, \%labels); #printLabels(\%labels); sub printLabels { my ($labels) = @_; foreach my $key (keys %$labels) { print "$key\n"; } } sub loadLines { my ($lines) = @_; while () { chomp; my $f = $_; loadLinesThisFile($lines, $f); } } sub loadFiles { my ($a, $f) = @_; my %labels = %$a; open(FILE, "<", $f) or die "$0: Cannot open $f : $!\n"; while () { if (/\\ptexReadFile\{([^\}]+)\}/) { my $file = $1; if ($doc_root != "") { $file = $doc_root . "/" . $file; } my $ret = open(FILE2, "<", $file); if (!$ret) { close(FILE); die "$0: ERROR: Cannot read $file, line $_\n"; } my $isMdFile = ($file=~/\.md$/); my $buffer = ""; while () { if ($isMdFile) { s/^# +(.*)/\\chapter\{$1\}/; s/^## +(.*)/\\section\{$1\}/; s/^### +(.*)\n$/\\subsection\{$1\}/; s/\\\@/\@/g; s//\{\\bf /; s/<\/b>/\}/; s/
/\\begin\{verbatim\}\n/;
					s/<\/pre>/\\end\{verbatim\}\n/;
					s//\{\\tt /g;
					s/<\/code>/\}/g;
				}

				$buffer .= $_;
			}

			close(FILE2);

			my $label = getLabelForFile($file);
			my @temp = ($buffer);
			$labels{"$label"} = \@temp;
			next;
		}
	}

	close(FILE);
	%$a = %labels;
}

sub loadLinesThisFile
{
	my ($lines, $f) = @_;

	open(FILE, "<", $f) or die "$0: Cannot open $f : $!\n";
	while () {
		chomp;
		push @$lines, $_;
	}

	close(FILE);
}

sub loadLabels
{
	my ($a, $lines) = @_;
	my %labels = %$a;
	my $label = "!DISABLED";
	my $additional = "";
	my $buffer = "";
	my $nlines = scalar(@$lines);
	my $inCodeBlock = 0;
	my $codeBuffer = "";
	my $modifyLater = 1;
	my $hasContinue = 0;

	for (my $i = 0; $i < $nlines; ++$i) {
		$_ = $lines->[$i];
		if (/\/\* *PSIDOC_RESUME */) {
			$hasContinue = 0;
			next;
		}

		if (/\/\* *PSIDOC +(.+$)/) {
			my $rest = $1;
			chomp($rest);
			checkThatItDoesNotHaveContinue($hasContinue, "PSIDOC $rest");
			($label, $additional) = procPsidocName($rest);
			$modifyLater = 1;

			my $txt = $labels{"$label"};
			if (defined($txt)) {
				die "$0: ERROR: Label $label is duplicate\n";
			}

			next;
		}

		if (/\/\* PSIDOC_CODE_START +(.+$)/) {
			my $rest = $1;
            chomp($rest);
			checkThatItDoesNotHaveContinue($hasContinue, "PSIDOC_CODE_START $rest");
			$rest =~ s/\*\/ *$//;
			if ($inCodeBlock) {
				die "$0: Nested code blocks not allowed\n";
			}

			($label, $additional) = procPsidocName($rest);
			$label =~ s/ //g;
			$modifyLater = ($additional eq "nocapture") ? 0 : 1;

			my $txt = $labels{"$label"};
			if (defined($txt)) {
				die "$0: ERROR: Label $label is duplicate\n";
			}

			$inCodeBlock = 1;
			next;
		}

		if (/\/\* PSIDOC_CODE_END \*\//) {
			if (!$inCodeBlock) {
				die "$0: Closing code block while none is open\n";
			}

			$labels{"$label"} = [$codeBuffer];
			$codeBuffer = "";
			$inCodeBlock = 0;
			next;
		}

		if (/\*\//) {
			next if ($hasContinue);
			if ($label ne "!DISABLED" and $modifyLater) {
				my $inlabel = $label."::";
				$buffer =~ s/PSIDOCCOPY \$/PSIDOCCOPY ${inlabel}/g;
				my @temp = ($buffer);
				$labels{"$label"} = \@temp;
				my $proto = captureFirstProtoBelow($i + 1, \@lines);
				if ($proto) {
					my @temp = ($proto);
					my $name = $inlabel."FirstProtoBelow";
					$labels{"$name"} = \@temp;
				}

				my $debug = 0;
				my $hashMark = captureFirstFunctionBelow($i + 1, \@lines, $debug);
				foreach my $key (%$hashMark) {
					my $func = $hashMark->{"$key"};
					next unless ($func);
					my @temp = ($func);
					my $name = $inlabel."FirstFunctionBelow";
					$name .= "::$key" unless ($key eq " ");
					$labels{"$name"} = \@temp;
				}
			}

			$buffer = "";
			$label = "!DISABLED";
			$modifyLater = 1;
			$additional = "";
		} elsif ($inCodeBlock) {
			$codeBuffer .= $_."\n";
			next;
		}

		if (/^[ \t]*PSIDOC_CONTINUE *$/) {
			$hasContinue = 1;
			next;
		}

		if ($label ne "!DISABLED") {
			$buffer .= $_."\n";
		}
	}

	if ($inCodeBlock) {
		die "$0: Code block was not closed for label $label\n";
	}

	my $n = scalar(%labels);
	print STDERR "$0: $n labels found\n";

	%$a = %labels;
}

sub checkThatItDoesNotHaveContinue
{
	my ($hasContinue, $txt) = @_;
	return if ($hasContinue == 0);
	die "$0: Cannot use $txt when has continue\n";
}

sub procPsidocName
{
	my ($nameLike) = @_;
	my @temp = split/[ \t]/,$nameLike;
	my $n = scalar(@temp);
	die "$0: procPsidocName empty\n" if ($n == 0);
	return $nameLike if ($n == 1);
	die "$0: procPsidocName more than one additional\n" if ($n > 2);
	return @temp;
}

sub captureFirstProtoBelow
{
	my ($ind, $lines) = @_;
	my $nlines = scalar(@$lines);
	my $buffer = "";
	for (my $i = $ind; $i < $nlines; ++$i) {
		$_ = $lines->[$i];
		last if (/\/\*/);
		next if (/^ *\/\//);
		$buffer .= $_."\n";
		last if (/\;/);
	}

	return $buffer if ($buffer eq "");

	$buffer =~ s/\t/  /g;
	$buffer = "\\begin{lstlisting}\n$buffer\n";
	$buffer .= "\\end{lstlisting}\n";

	return $buffer;
}

sub captureFirstFunctionBelow
{
	my ($ind, $lines, $debug) = @_;
	my $nlines = scalar(@$lines);
	my $buffer = "";
	my $level = 0;
	my $markName = "";
	my $markContent = "";
	my %markHash;
	for (my $i = $ind; $i < $nlines; ++$i) {
		my $line = $lines->[$i];
		if ($line =~ /^[ \t]*\/\/ *PSIDOCMARK\_BEGIN +(.+$)/) {
			die "$0: PSIDOCMARK_BEGIN $1 cannot be nested\n" if ($markName ne "");
			$markName = $1;
			next;
		}

		if ($line =~ /^[ \t]*\/\/ *PSIDOCMARK\_END/) {
			die "$0: PSIDOCMARK_END found but no mark open\n" if ($markName eq "");
			$markHash{"$markName"} = dressCode($markContent);
			$markName = $markContent = "";
			next;
		}

		last if ($line =~ /\/\*/);
		next if ($line =~ /^ *\/\//);
		$buffer .= "$line\n";

		$markContent .= "$line\n" if ($markName ne "");
		my $plus = () = $line =~ /\{/g;
		my $minus = () = $line =~ /\}/g;
		$level += $plus;
		$level -= $minus;
		print "$line **$level**\n" if ($debug);
		last if ($line =~ /\}[^\{\}]*$/ and $level == 0);
	}

	die "$0: PSIDOCMARK_BEGIN $1 was never ended\n" if ($markName ne "");

	$buffer = "" unless ($level == 0);
	$markHash{" "} = $buffer;
	return \%markHash if ($buffer eq "");

	$markHash{" "} = dressCode($buffer);
	return \%markHash;
}

sub dressCode
{
	my ($code) = @_;
	$code =~ s/\t/  /g;
	$code = "\\begin{lstlisting}\n$code\n";
	$code .= "\\end{lstlisting}\n";
	return $code;
}

sub replaceLabels
{
	my ($file, $a) = @_;
	my $fout = $file;
	if ($out_dir != "") {
	    $fout =~ s/.*\///; #chop the beginning of the path
	    $fout =  $out_dir . "/" . $fout;
	}
	$fout=~s/\.ptex$/\.tex/;
	die "$0: $file must have extension .ptex\n" if ($file eq $fout);

	open(FOUT, ">", "$fout") or die "$0: Cannot write to $fout : $!\n";
	open(FILE, "<", $file) or die "$0: Cannot open $file : $!\n";
	while () {
		next if (/^[ \t]*%/);
		if (/\\ptexPaste\{([^\}]+)\}/) {
			my $label = $1;
			next if ($label eq "#1");
			my $txt = getTextFromLabel($label,$a);
			if (!defined($txt)) {
				$txt = labelNotFound($label);
			}

			print FOUT $txt;
			next;
		}

		if (/\\ptexReadFile\{([^\}]+)\}/) {
			my $file=$1;
			my $label = getLabelForFile($file);
			my $txt = getTextFromLabel($label,$a);
			if (!defined($txt)) {
				$txt = labelNotFound($label,$file);
			}

			print FOUT $txt;
			next;
		}

		print FOUT;
	}


	close(FILE);
	close(FOUT);

	print STDERR "$0: File $fout written\n";
}

sub recursiveExpand
{
	my ($a) = @_;
	my %labels = %$a;

	my $recurse = 0;
	foreach my $key (keys %labels) {
		my $ptr = $labels{"$key"};
		defined($ptr) or die "$0: Label $key has error\n";
		scalar(@$ptr) > 0 or die "$0: Label $key has error\n";
		my $txt = $ptr->[0];
		next unless ($txt=~/PSIDOCCOPY/);
		my $txt2 = expandIfNeeded($txt,$a);
		$recurse = 1 if ($txt2=~/PSIDOCCOPY/);
		my @buffer = ($txt2);
		$ptr = \@buffer;
		$labels{"$key"}=$ptr;
	}

	%$a = %labels;

	recursiveExpand($a) if ($recurse);
}

sub expandIfNeeded
{
	my ($txt,$a) = @_;
	my %labels = %$a;
	my @temp = split/\n/,$txt;

	my $n = scalar(@temp);
	my $buffer = "";
	for (my $i = 0; $i < $n; ++$i) {
		$_ = $temp[$i];
		if (/PSIDOCCOPY +([^ ]+)/) {
			my $label = $1;
			chomp($label) if ($label=~/\n$/);
			my $txt = getTextFromLabel($label,$a);
			if (!defined($txt)) {
				die "$0: ERROR: line $_, $label not found\n";
				$txt = labelNotFound($label);
			}

			$buffer .= $txt;
			next;
		}

		$buffer .= $_."\n";
	}

	return $buffer;
}

sub getTextFromLabel
{
	my ($label,$a)=@_;
	my %labels = %$a;
	my $ptr = $labels{"$label"};
	my $txt;
	if (!defined($ptr) || scalar(@$ptr) < 1) {
		print STDERR "$0: ERROR: Label $label not found\n";
		return $txt;
	}

	return $ptr->[0];
}

sub getLabelForFile
{
	my ($file) = @_;

	$file=~s/\./DOT/g;
	$file=~s/\//SLASH/g;
	return "FILE$file";
}

sub labelNotFound
{
	my ($label,$file) = @_;
	my $str = (defined($file)) ? " in $file " : "";
	return "{\\bf\\textcolor{red}{ERROR: Label not found$str}}\n";
}

PsimagLite-3.06/scripts/format.pl000077500000000000000000000005001446452427400170260ustar00rootroot00000000000000#!/usr/bin/perl

use strict;
use warnings;
use utf8;

my @extensions=("*.hh", "*.h", "*.cc", "*.cpp");

my $opts = " --style=file -i ";
foreach my $ext (@extensions) {
	my $cmd = "find . -iname \"$ext\" -exec clang-format  $opts '{}' \\;";
	print STDERR "$0: Formated all files with extension $ext\n";
	system($cmd);
}

PsimagLite-3.06/scripts/functionSigIndent.pl000066400000000000000000000147121446452427400211770ustar00rootroot00000000000000#!/usr/bin/perl -w

use strict;

# [static const virtual] [type] name(arg1,arg2) [const]

my $multiLineComment = 0;
my $buffer="";
my $pristineBuffer="";

my @keywords=("for","if","while","struct","class","namespace");
my $GlobalSizeOfTab = 2;
my $GlobalMaxLine = 80;
my @GlobalCvQualifiers=("const","virtual","volatile","static");

while() {

	my $savedLine = $_;

	s/\/\*.*\*\///;
	s/\/\/.*$//;
	$multiLineComment = 1 if (/^[\t ]*\/\*/);
	
	if ($multiLineComment) {
		print $savedLine;
		$multiLineComment = 0 if (/\*\//);
		next;
	}

	# Empty lines:
	my $line = $_;
	$line=~s/[ \t]+//;
	$line=~s/\n//;
	$pristineBuffer .= $savedLine;
	if ($line eq "") {
		print $pristineBuffer;
		$pristineBuffer="";
		next;
	}

	# Buffer
	$buffer .= $_;

	if (/\{/) {
		my $needsPrinting = procBuffer($buffer);
		print $pristineBuffer if ($needsPrinting);
		$buffer="";
		$pristineBuffer="";
		next;
	}

	if (/\}[ \t]*$/ ||  /\:[ \t]*$/ || /\;[ \t]*$/) {
		$buffer = "" ;
		print $pristineBuffer;
		$pristineBuffer="";
	}
}

print $pristineBuffer;
$pristineBuffer="";

sub procBuffer
{
	my ($t)=@_;
	return 1 if ($t=~/\#define /);
	return 1 if ($t=~/\#include /);
	# Find first parens
	my $first="";
	my $second="";
	if ($t=~/(^[^\(]+)\(([^\)]*)\)/) {
		$first = $1;
		$second = $2;
	}
	return 1 if ($first eq "");

	
	my %func;
	$func{"post-qualifier"} = getPostQualifier($t);

	getFirstPart(\%func,$first);
	my $name = $func{"name"};
	return 1 if (isInVector(\@keywords,$name));

	printFunc(\%func);

	my @funcArgs=getArgs($second);
	for (my $i=0;$i<=$#funcArgs;$i++) {
		print STDERR " ~ $funcArgs[$i] ";
	}
	my $length=computeLength(\%func,\@funcArgs);
	print STDERR " LENGTH=$length\n";
	print STDERR "\n-----------------------------\n";
	return 1 if ($length<$GlobalMaxLine || $#funcArgs<1);
	rewriteSig(\%func,\@funcArgs);
	return 0;
}

sub getFirstPart
{
	my ($f,$first)=@_;
	$$f{"level"}=getLevel($first);
	$first=~s/\n/\@ /g;
	$_=$first;
	my @temp=split;
	my $n = $#temp+1;
	if ($n==1) { # It's a constructor or destructor
		$$f{"pre-qualifier"}="";
		$$f{"type"}="";
		$$f{"name"}=$temp[0];
		return;
	}
	if ($n==2) { # unqualified function or destructor
		if ($temp[1]=~/^\~/) { # destructor
			$$f{"pre-qualifier"}=$temp[0];
			$$f{"type"}="";
			$$f{"name"}=$temp[1];
			return;
		}
		# unqualified function
		$$f{"pre-qualifier"}="";
		$$f{"type"}=$temp[0];
		$$f{"name"}=$temp[1];
		return;
	}

	# $n>2 --> qualified function
	$_=$first;
	s/[^ \t]+[\t ]*$//; # kill name
	s/[^ \t]+[\t ]*$//; #kill type
	s/^[\t ]*//;
	s/[\t ]*$//;
	$$f{"pre-qualifier"} = $_;
	$$f{"name"}=$temp[$n-1];
	$$f{"type"}=$temp[$n-2];
}

sub getPostQualifier
{
	my ($t)=@_;
	my $ret = "";
	$t=~s/\n/\@/g;
	if ($t=~/\)(.*$)/) {
		$ret = $1;
		$ret =~ s/[ \t]+$//g;
	}
	return $ret;
}

sub getLevel
{
	my ($t)=@_;
	$_=$t;
	if ($t=~/\n/) {
		my @temp=split/\n/;
		$_=$temp[$#temp];
	}
	#print STDERR "HERE $_\n";
	my $counter=0;
	while(s/^\t//) {
		#print STDERR "*".$1."*\n";
		$counter++;
	}
	
	return $counter;
}

sub getArgs
{
	my ($t)=@_;
	return if ($t eq "");
	$_ = $t;
	my @fa=split/,/;
	my $n = $#fa+1;
	for (my $i=0;$i<$n;$i++) {
		$fa[$i]=~s/^[\t ]+//;
		$fa[$i]=~s/[\t ]+$//;
		$fa[$i]=~s/[\n\r]//g;
	}
	return glueArgs(\@fa);
}

sub glueArgs
{
	my ($fa)=@_;
	my @ret;
	my $buffer="";
	my $openFlag=0;
	my $n = scalar(@$fa);
	my $counter=0;
	for (my $i=0;$i<$n;$i++) {
		$buffer .= "," unless ($buffer eq "");
		$_ = $fa->[$i];
		s/^[\t ]*//;
		s/[\t ]*$//;
		$buffer .= $_;
		$openFlag += countChars($fa->[$i],"<");
		$openFlag -= countChars($fa->[$i],">");
		if ($openFlag==0) {
			$ret[$counter++]=$buffer;
			$buffer="";
		}
	}
# 	$ret[$counter++]=$buffer;
# 	$buffer="";
	return @ret;
}

sub countChars
{
	my ($t,$c)=@_;
	$_=$t;
	my $counter=0;
	while(s/\Q$c//) {
		$counter++;
	}
	return $counter;
}

sub isInVector
{
	my ($vec,$what)=@_;
	foreach (@$vec) {
		return 1 if ($what eq $_);
	}
	return 0;
}

sub printFunc
{
	my ($f)=@_;
	foreach (keys %$f) {
		my $val = $$f{"$_"};
		print STDERR "$_=$val ";
	}
}

sub computeLength
{
	my ($f,$fa)=@_;
	my $sum = 0;
	my $sp = 0;
	foreach (keys %$f) {
		my $val = $$f{"$_"};
		next if ($val eq "");
		if ($_ eq "level") {
			$sum += $val*$GlobalSizeOfTab;
			next;
		}
		$sum += length($val);		
		$sp++; # leave a space
	}
	$sp-- if ($sp>0); # substract last space if any
	
	$sum += 2; # add both parens
	
	my $cma = 0;
	foreach (@$fa) {
		next if ($_ eq "");
		$sum += length($_);
		$cma++; # comma between args
	}
	$cma-- if ($cma>0); # substract last comma if any
	return $sum + $cma + $sp;
}

sub rewriteSig
{
	my ($f,$fa)=@_;
	 #[pre-qualifier] [type] name(arg1,
     #                            arg2,
     #                            ...) [post-qualifier]
     #{
	
	my $level = $$f{"level"};
	$$f{"pre-qualifier"} = templatedFunction($$f{"pre-qualifier"},$level);
	printChars($level,"\t");
	$_ = $$f{"pre-qualifier"};
	print "$_ " unless ($_ eq "");
	my $count = length($_);
	$_ = $$f{"type"};
	print "$_ " unless ($_ eq "");
	$count += length($_);
	$count-- if ($_ eq "");
	$_ = $$f{"name"}."(";
	print "$_" unless ($_ eq "");
	$count += length($_);
	$count++;
	# print arguments, note that we have at least 2 arg.
	my $n = scalar(@$fa);
	($n>1) or die "rewriteSig should not have been called, n=$n\n";

	#first arg.
	$_=$fa->[0].",\n";
	print "$_";
	for (my $i=1;$i<$n-1;$i++) {
		printChars($level,"\t");
		printChars($count," ");
		$_=$fa->[$i].",\n";
		s/^[ \t]+//;
		print "$_";
	}

	# last arg
	printChars($level,"\t");
	printChars($count," ");
	$_=$fa->[$n-1];
	s/^[ \t]+//;
	s/[ \t]*$//;
	print "$_".")";
	printPostQualifier($$f{"post-qualifier"},$level);
	#s/^[ \t]+//;
	#s/[\r\n]//g;
	#print " $_" unless ($_ eq "");
	#print "\n";
	#printChars($level,"\t");
	#print "{\n";
	
}

sub printPostQualifier
{
	my ($pq,$level)=@_;

	return if ($pq eq "");

	if (!($pq=~/\@/)) {
		$pq=~s/[\t ]*$//;
		print "$pq\n";
		return;
	}

	$_=$pq;
	my @temp = split/\@/;
	$_=shift @temp;
	print  "$_\n";
	foreach (@temp) {
		#printChars($level,"\t");
		s/[\t ]*$//;
		print "$_\n"
	}
}

sub templatedFunction
{
	my ($t,$level)=@_;
	
	return $t unless ($t=~/[\t ]*template[ \<]/);
	my ($templ,$cvq)=getCvQualifiers($t);
	printChars($level,"\t");
	print "$templ\n";
	return $cvq;
}

sub getCvQualifiers
{
	my ($t)=@_;
	my ($templ,$cvq)=($t,"");
	$_=$t;
	while(s/([^ \t]+)[\t ]*$//) {
		if (isInVector(\@GlobalCvQualifiers,$1)) {
			$cvq=$1." ";
			$templ=$_;
		} else {
			last;
		}
	}
	$cvq=~s/[\t ]*$//;
	$templ=~s/\@/\n/g;
	$templ=~s/[\n \t]*$//;
	return ($templ,$cvq);
}

sub printChars
{
	my ($n,$c)=@_;
	for (my $i=0;$i<$n;$i++) { print "$c"; } 
}
PsimagLite-3.06/scripts/indentStrict.pl000066400000000000000000000206311446452427400202140ustar00rootroot00000000000000#!/usr/bin/perl  -w
use strict;
use Getopt::Long;

my ($file,$noerrors,$nowarn,$debug,$fix)=("YOU MUST SPECIFY -file filename",0,0,0);
defined($file) or die "$0: Needs one argument: the filename\n";
GetOptions ("ne" => \$noerrors,    # do not display errors
	"nw"   => \$nowarn,      # do not display warnings
	"fix"  => \$fix,
	"d" => \$debug,
	"file=s"=>\$file);  # fix in place
print STDERR "$0: Echo of command line: $file $noerrors $nowarn $debug\n";

my $indentLevel = 0;
my $line = 0;
my $consecutiveEmptyLine=0;
my $closeAfterNext = 0;
my $braceAtTheEnd = 0;
my $nextLineMustBeEmpty = 0;
my @mystack;
my $sizeOfTabs = 4;
my $comment = 0;
my @tooLongLines;
my $namespacesOpen = 0;
my $lastLabel = "NO_LABEL";

my $fout = "tmp.txt";
open(FILE, "<", $file) or die "Cannot open file $file: $!\n";
open(FOUT, ">", "$fout") or die "Cannot open file $fout for writing: $!\n";
my $lforEcho = "";
my $appendNext = 0;
my $parensBalance = 0;

while() {
	if ($appendNext) {
		$lforEcho .= $_;
	} else {
		$lforEcho = $_;
	}

	if (/\\$/) {
		$appendNext = 1;
		$line++;
		next;
	} else {
		$appendNext = 0;
	}

	chomp;
	$line++;

	if ($lforEcho=~/^[\t ]+\#/) {
		die "FATAL: Line $.: preprocessor directives must start at line 0\n";
	}

	if ($lforEcho=~/^\#/) {
		print FOUT $lforEcho;
		$consecutiveEmptyLine = 0;
		next;
	}
	if (/^[\t]+DO_IF_DEBUG/) {
		print STDERR "Warning: Ignoring line $.\n" unless ($nowarn);
		print FOUT $lforEcho;
		$consecutiveEmptyLine = 0;
		next;
	}

	# ignore comments
	my $cmt = "";
	if (s/([\t ]*\/\/.*$)//) {
		$cmt = $1;
		$consecutiveEmptyLine = 0;
	}
	if (s/([\t ]*\/\*.+\*\/[\t ]*)//) {
		$cmt .= $1;
		$consecutiveEmptyLine = 0;
	}
	$comment = 1 if (/\/\*/);
	if (/\*\//) {
		$comment = 0;
		$cmt .= $1 if s/(^.*\*\/)//;
		$consecutiveEmptyLine = 0;
	}
	if ($comment) {
		print  FOUT $lforEcho;
		next;
	}

	my $r = $_;
	$r =~ s/[\t ]//g;
	if (length($r)==0) {
		# empty line:
		if (length($_)>0) {
			print "ERROR: Empty line $line has whitespace\n" unless ($noerrors);
			
			my $cpy = $lforEcho;
			$lforEcho = "";
			while ($cpy =~ s/(\/\*.+\*\/)//) {
				$lforEcho .= $1;
			}
			$cpy =~ s/^[\t ]*(\/\/.*$)/$1/;
			$lforEcho .= $cpy;
			$cpy =~s/[\t ]//g;
			chomp($cpy);
			if (length($cpy)==0) {
				$lforEcho ="\n";
			}
		}
		($consecutiveEmptyLine==0 or length($cmt)>0) or die "FATAL: Two consecutive empty lines at $line\n";
		$consecutiveEmptyLine++ if (length($cmt)==0);
		$nextLineMustBeEmpty = 0;
		print FOUT $lforEcho;
		next;
	} 
	if ($nextLineMustBeEmpty!=0) {
		my $r = $_;
		$r =~ s/[\t ]//g;
		($r eq "}" or $r eq "};") or die "FATAL: Line $line must be empty to comply with rule -bap\n";
	}
	$consecutiveEmptyLine=0;
	
	#check ending space
	if (/[\t ]+$/) {
		$lforEcho =~ s/[\t ]+$//;
		print "ERROR: Ending whitespace in line $line\n" unless ($noerrors);
	}
	
	# space after ( or before )
	if (/\( ([a-zA-Z0-9])/ || /([a-zA-Z0-9]) \)/) {
		$lforEcho =~s/\( ([a-zA-Z0-9])/\($1/;
		$lforEcho =~s/([a-zA-Z0-9]) \)/$1\)/;
		print "ERROR: Space after ( or before ) in line $line goes against rule -nprs and/or -npcs\n" unless ($noerrors);
	}

	# space after if for or while or foreach 
	if (/if\(/ or /for\(/ or /while\(/ or /foreach\(/) {
		$lforEcho =~s/if\(/if \(/;
		$lforEcho =~s/for\(/for \(/;
		$lforEcho =~s/while\(/while \(/;
		$lforEcho =~s/foreach\(/foreach \(/;
		print "ERROR: Lack of space after if/for/foreach/while in line $line goes against rule -sai -saf -saw\n" unless ($noerrors);
	}

	# size_t is deprecated
	if (/size_t /) {
		print "WARNING: size_t is deprecated. Use SizeType instead\n" unless ($nowarn);
	}
	
	# std::vector, std::map and std::stack are deprecated
	my @stdclasses = ("vector","map","stack");
	foreach my $stdclass (@stdclasses) {
		if (/std::$stdclass<([^>]+)>/) {
			my $capitalclass = ucfirst($stdclass);
			print "WARNING: std::$stdclass is deprecated. Include \"$capitalclass.h\" and use [typename] PsimagLite::$capitalclass<$1>::Type instead.\n"
			unless ($nowarn);
		}
	}

	# std::string is deprecated
	my @stringclasses = ("string","istringstream","ostringstream","logic_error","range_error","runtime_error");
	foreach my $stringclass (@stringclasses) {
		if (/std::$stringclass /) {
			my $capitalclass = ucfirst($stringclass);
			if ($capitalclass =~ /_(.{1})/) {
				my $tmp = uc($1);
				$capitalclass =~ s/_(.{1})/$tmp/;
			}
			print "WARNING: std::$stringclass is deprecated. Include \"String.h\" and use PsimagLite::$capitalclass instead\n" unless ($nowarn);
		}
	}

	# line length
	$r = $_;
	$r =~ s/\t//g;
	my $ll = length($r);
	$r = $_;
	$r =~ s/[^\t]//g;
	$ll += length($r) * $sizeOfTabs;
	($ll<=90) or push @tooLongLines,($line,$ll);
	# check indentation level
	my $o = $_;
	if ($closeAfterNext>0) {
		my $br = "";
		for (my $i=0;$i<$closeAfterNext;$i++) {
			$br .= "}";
		}
		if ($o =~ s/\;[\t ]*$/\Q$br/) {
			$braceAtTheEnd = 1;
			$closeAfterNext =0;
		}
	}
	my $c = $o;
	$o =~ s/\"[^\"]+\"//;
	$o =~ s/[^\{]//g;
	my $co = length($o);
	my $hasSemicolonAtTheEnd = 0;
	if (/\;[\t ]*$/) {
		$hasSemicolonAtTheEnd = 1;
	}

	my $parensOpen = $_;
	$parensOpen =~ s/[^\(]//g;
	$parensOpen = length($parensOpen);

	my $parensClosed = $_;
	$parensClosed =~ s/[^\)]//g;
	$parensClosed = length($parensClosed);
	$parensBalance += ($parensOpen - $parensClosed);

	my $label = getLabel($_);

	if ($co==0 and !$hasSemicolonAtTheEnd) {
		 my @whats = ("else if","if","for","foreach","else","switch","try","catch");
		 my $flagTmp = 0;
		 foreach my $what (@whats) {
			if ($label eq $what) {
				$flagTmp = 1;
				last;
			}
		}
		if ($flagTmp) {
			$parensBalance = $parensOpen - $parensClosed;
			if ($parensBalance==0) {
				$co = 1;
				$closeAfterNext++;
			}	
		}
	}

	push @mystack, $label if ($co==1);
	$c =~ s/\"[^\"]+\"//;
	$c =~ s/[^\}]//g;
	my $cc = length($c);
	if ($cc==1) {
		my $tmp = pop @mystack;
		$label = $tmp;
		if ($tmp eq "function") {
			$nextLineMustBeEmpty = 1;
		}
	}
	my $tmpLevel = $indentLevel;
	$indentLevel += ($co-$cc);
	if ($debug) {
		print STDERR "Line $.: tmplevel= $tmpLevel indentLevel= $indentLevel balance=$parensBalance co=$co cc=$cc label=$label\n";
		printList(\@mystack);
	}
	$tmpLevel = $indentLevel if ($co<$cc and !$braceAtTheEnd);
	if ($tmpLevel>0 and ($label eq "else" or $label eq "catch" or $label eq "else if") and $co>0) {
		$tmpLevel-- if ($_=~/} $label .*\{$/);
	}
	
	#print "$_ ** $line ** $indentLevel \n"  if ($co<$cc and !$braceAtTheEnd);
	$braceAtTheEnd = 0;
	
	#check for public or private:
	if (/public\:/ || /private\:/ || /protected\:/ || /case [^\:]+\:/  || /default\:/) {
		$tmpLevel-- if ($tmpLevel>0);
	}

	#close namespace if needed
	if ($tmpLevel<$namespacesOpen) {
		print STDERR "Closing namespace namespacesOpen = $namespacesOpen\n";
		$namespacesOpen--; #= ($tmpLevel+1);
	}
	# check trailing whitespace
	my $w = $_;
	$w =~ /(^[ \t]*)(.*$)/;	
	checkTrailingWhite($1,$tmpLevel,$label);

	$namespacesOpen++ if ($label eq "namespace" and length($o)>0);

	print FOUT $lforEcho;
}

close(FILE);
close(FOUT);

printWarnings() unless ($nowarn);

if ($fix) {
	print STDERR "$0: Copying $file into $file.bak\n";
	system("cp $file $file.bak");
	print STDERR "$0: Copying $fout into $file\n";
	system("cp $fout $file");
}

sub printWarnings
{
	my $n = scalar(@tooLongLines);
	return if ($n == 0);
	my $c = 0;
	print "LINE\tLENGTH (tabsize=$sizeOfTabs)\n";
	foreach (@tooLongLines) {
		if ($c%2==0) {
			print "$_ ";
		} else {
			print "$_\n";
		}
		$c++;
	}
}

sub checkTrailingWhite
{
	my ($w,$inLevel,$label) = @_;
	# space before tabs is an error:
	if ($w =~ / \t/) {
		$lforEcho =~ s/(^ +)\t/\t/;
		print "ERROR: Space before tab found in line $line\n" unless ($noerrors);
	}
	my $tbs = $w;
	$tbs =~ s/[^\t]//g;
	my $ctbs = length($tbs);

	$inLevel -= $namespacesOpen;
	($ctbs==$inLevel) or die "$0: FATAL: Indentation level $inLevel tabs $ctbs, for line $line label=$label namespaces=$namespacesOpen\n";
}

sub getLabel
{
	my ($t)=@_;
	my $tt = $t;
	
	$tt =~ s/\".+\"//;
	
	my $label = $lastLabel;
	my $flag=0;
	my @whats = ("class","namespace","else if","if","for","foreach","else","enum","switch","return","try","catch");

	foreach my $what (@whats) {
		if (isOfType($tt,$what)) {
			$label = $what;
			$flag = 1;
			last;
		}
	}

	if (!$flag) {
		$label = "function";
	}

	$lastLabel = $label;
	return $label;
}

sub isOfType
{
	my ($tt,$what) = @_;
	return 1 if ($tt=~/^$what/);
	return 1 if ($tt=~/[ \t]+$what$/);
	return 1 if ($tt=~/[ \t]+$what[^a-zA-Z]/);
	return 0;
}

sub printList
{
	my ($a)= @_;
	my $n = scalar(@$a);
	for (my $i = 0; $i < $n; $i++) {
		print STDERR "$a->[$i] ";
	}
	print STDERR "\n";
}

PsimagLite-3.06/scripts/lorentzian.pl000077500000000000000000000035271446452427400177370ustar00rootroot00000000000000#!/usr/bin/perl

use strict;
use warnings;
use utf8;

#The file to be read has format
#omega0 weight0
#omega1 weight1
#...
#
my ($file, $wbegin, $wtotal, $wstep, $delta, $norm) = @ARGV;
defined($delta) or die "USAGE: $0 filename omegaBegin omegaTotal omegaStep delta [norm]\n";

print "#$file, $wbegin, $wtotal, $wstep, $delta\n";
my @data = loadData($file);

my $wstruct = {
	"begin" => $wbegin,
	"total" => $wtotal,
	"step" => $wstep,
	"delta" => $delta};

my @data2 = computeData(\@data, $wstruct);

my $sumptr = pop @data2;

my $sum = $sumptr->[1];

my $factor = defined($norm) ? $norm/$sum : 1;

plotData(\@data2, $factor);

sub plotData
{

	my ($data, $factor) = @_;
	my $n = scalar(@$data);
	for (my $i = 0; $i < $n; ++$i) {
		my $ptr = $data->[$i];
		my $omega = $ptr->[0];
		my $val = $factor * $ptr->[1];
		print "$omega $val\n";
	}
}

sub computeData
{
	my ($data, $wstruct) = @_;
	my @data2;
	my $sum = 0;
	for (my $i = 0; $i < $wstruct->{"total"}; ++$i) {
		my $omega = $wstruct->{"begin"} + $wstruct->{"step"}*$i;
		my $val = computeValueFor($omega, $data, $wstruct->{"delta"});
		$data2[$i] = [$omega, $val];
		$sum += $val;
		#print "$omega $val\n";
	}

	push @data2, [0, $sum];
	return @data2;
}

sub computeValueFor
{
	my ($omega, $data, $delta) = @_;

	my $sum = 0;
	my $total = scalar(@$data);
	for (my $i = 0; $i < $total; ++$i) {
		my $ptr = $data->[$i];
		my $deltaOmega = $omega - $ptr->[0];
		$sum += $ptr->[1]/($deltaOmega*$deltaOmega + $delta*$delta);
	}

	return $sum;
}

sub loadData
{
	my ($file) = @_;
	open(FILE, "<", "$file") or die "$0: Cannot open $file : $!\n";

	my @data;
	my $count = 0;
	while () {
		next if (/^#/);
		my @temp = split;
		my $n = scalar(@temp);
		die "$0: Expected 2 values not $n values\n" unless ($n == 2);
		$data[$count++] = \@temp;
	}

	close(FILE);

	print STDERR "$0: Found $count peaks\n";
	return @data;
}


PsimagLite-3.06/scripts/mpiRoundRobin.pl000077500000000000000000000015361446452427400203370ustar00rootroot00000000000000#!/usr/bin/perl

use strict;
use warnings;
use utf8;

my ($file, $mpiJobs) = @ARGV;
defined($file) or die "USAGE: $0 filename\n";

my %h;
my $firstNode;
open(FILE, "<", "$file") or die "$0: Cannot open $file : $!\n";
while () {
	chomp;
	next if (/^#/ or $_ eq "");
	my $f = $_;
	$firstNode = $f;
	if (!defined($h{"$f"})) {
		$h{"$f"} = 1;
	} else {
		++$h{"$f"};
	}
}

close(FILE);

my $nodes = scalar(keys %h);
die "$0: Nodes $nodes must be a multiple of mpiJobs $mpiJobs\n" if ($mpiJobs % $nodes != 0);

die "$0: No nodes!\n" if ($nodes == 0 or !defined($firstNode));
my $ppn = $h{"$firstNode"};
my $repeat = $mpiJobs/$nodes;

my $firstcall = 1;
for (my $i = 0; $i < $repeat; ++$i) {
	foreach my $key (sort keys %h) {
		my $n = $h{"$key"};
		next if ($n == 0);
		if ($firstcall) {
			$firstcall = 0;
		} else {
			print ",";
		}
	
		print "$key";
	}
}


PsimagLite-3.06/scripts/naiztnerol.pl000077500000000000000000000052261446452427400177350ustar00rootroot00000000000000#!/usr/bin/perl

use strict;
use warnings;
use utf8;

#The file to be read has format
#omega value
#
my ($file, $midPointFactor) = @ARGV;
defined($file) or die "USAGE: $0 filename [midPointFactor]\n";
defined($midPointFactor) or $midPointFactor = 0.75;

print "#$file \n";
my @data = loadData($file);

my @data2 = findMaxima(\@data);

#printMaxima(\@data2);
naiztnerol(\@data, \@data2);

sub naiztnerol
{
	my ($data, $data2) = @_;
	my $n = scalar(@$data2);
	 for (my $i = 0; $i < $n; ++$i) {
		 my $ptr = $data2->[$i];
		 my $omega = $ptr->[0];
		 my $val = $ptr->[1];
		 my $omegaStartIndex = $ptr->[2];
		 my $midVal = $val*$midPointFactor;
		 my $omegaMidIndex = findMidOmegaIndex($midVal, $omegaStartIndex, $data);
		 my $omegaMid = $data->[$omegaMidIndex]->[0];
		 $midVal = $data->[$omegaMidIndex]->[1]; # recomputed
		 my ($A, $delta) = findWeightAndDelta($omega, $val, $omegaMid, $midVal);
		 print "$omega $A $delta\n";
	 }
}

sub findWeightAndDelta
{
	my ($omegaMax, $maxVal, $omegaMid, $midVal) = @_;
	my $den = $maxVal/$midVal - 1;
	die "$0: Negative sqrt arg $den\n" if ($den <= 0);
	$den = sqrt($den);
	my $delta = ($omegaMid - $omegaMax)/$den;
	my $A = $maxVal*$delta*$delta;
	return ($A, $delta);
}

sub findMidOmegaIndex
{
	my ($midVal, $start, $data) = @_;
	my $n = scalar(@$data);
	my $prevVal = 0;
	for (my $i = $start; $i < $n; ++$i) {
		my $val = $data->[$i]->[1];
		if ($prevVal > $midVal and $val < $midVal) {
			return $i;
		}

		$prevVal = $val;
	}

	die "$0: findMidOmegaIndex failed!?\n";
}

sub printMaxima
{
	my ($data) = @_;
	my $n = scalar(@$data);
	for (my $i = 0; $i < $n; ++$i) {
		my $ptr = $data->[$i];
		my $omega = $ptr->[0];
		my $val = $ptr->[1];
		print "$omega $val\n";
	}
}

sub findMaxima
{
	my ($data) = @_;
	my $n = scalar(@$data);
	my @data2;
	my ($maxVal, $maxOmega, $maxOmegaIndex, $prevVal) = (0, 0, 0, 0);
	for (my $i = 0; $i < $n; ++$i) {
		my $ptr = $data->[$i];
		my $omega = $ptr->[0];
		my $val = $ptr->[1];

		if ($val > $prevVal) {
			#going up
			if ($val > $maxVal) {
				$maxVal = $val;
				$maxOmega = $omega;
				$maxOmegaIndex = $i;
			}
		} else {
			#going down
			if ($maxVal > 0) {
				push @data2, [$maxOmega, $maxVal, $maxOmegaIndex];
				$maxVal = 0;
			}
		}

		$prevVal = $val;
	}

	print STDERR "$0: Found ".scalar(@data2)." maxima\n";
	return @data2;
}

sub loadData
{
	my ($file) = @_;
	open(FILE, "<", "$file") or die "$0: Cannot open $file : $!\n";

	my @data;
	my $count = 0;
	while () {
		next if (/^#/);
		my @temp = split;
		my $n = scalar(@temp);
		die "$0: Expected 2 values not $n values\n" unless ($n == 2);
		$data[$count++] = \@temp;
	}

	close(FILE);

	print STDERR "$0: Found $count values\n";
	return @data;
}


PsimagLite-3.06/scripts/pTeX.pl000066400000000000000000000113671446452427400164300ustar00rootroot00000000000000#!/usr/bin/perl -w

use warnings;
use strict;
use File::Find::Rule;
use lib ".";
use FunctionParsing;

=pod
Usage:
perl ptex.pl < source.ptex > destination.tex
=cut

my $ptexStartKeyword = "!PTEX-START";
my $ptexInterfaceKeyword = "!PTEX-START-INTERFACE";
my $ptexEndKeyword = "!PTEX-END";
my $ptexThisClassKeyword="!PTEX_THISCLASS";
my $ptexThisFunctionKeyword="!PTEX_THISFUNCTION";
my $ptexRefKeyword="!PTEX_REF";
my $ptexLabelKeyword="!PTEX_LABEL";

my %GlobalMacros=();
my %GlobalRefs=();
my $GlobalPtexOpen=0;
my $GlobalLabel="";
my $GlobalBuffer="";
my $GlobalIsInterface;

print STDERR "$0: This script is deprecated, please use PsimagDoc found also in this repository\n";

loadMacros(0);
loadMacros(1);

printHeader();
replaceMacros();

sub replaceMacros
{
	while() {
		
		next if (/\\newcommand\{\\ptex/);

		if (/\\ptexPaste\{([^\}]+)\}/) {
			my $x = $GlobalMacros{$1};
			die "Undefined macro for label $1, line $.\n" if (!defined($x));
			my %xx = %$x;
			my $data = $xx{"data"};
			die "Undefined macro for label $1\n" if (!defined($data));
			s/\\ptexPaste\{([^\}]+)\}/$data/;
		}

		if (/\\ptexLabel\{([^\}]+)\}/) {
			die "Undefined ref for label $1\n" if (!defined($GlobalRefs{$1}));
			s/\\ptexLabel\{([^\}]+)\}/$GlobalRefs{$1}/g;
			print;
		}
		
		
		if (/\\ptexInterface\{([^\}]+)\}/) {
			printInterface($1);
			next;
		}

		if (/\\ptexReadFileVerbatim\{([^\}]+)\}/) {
			readFileVerbatim($1);
			next;
		}

		if (/\\ptexReadFile\{([^\}]+)\}/) {
			readFile($1);
			next;
		}
		next if (/\!PTEX\-/);
		print;
	}
}

sub printHeader
{
my $date=`date`;
chomp($date);
print<file()->name("*.h")
                                ->in("../src");
	foreach my $file (@files) {
		procThisFile($file,$passNumber);
		procThisFile($file,$passNumber+10);
	}
}

sub procThisFile
{
	my ($file,$passNumber)=@_;
	$GlobalPtexOpen=0;
	$GlobalLabel="";
	$GlobalBuffer="";
	$GlobalIsInterface = 0;
	open(FILE, "<", $file) or die "Cannot open file $file: $!\n";
	while() {
		procThisLine($_,$file,$passNumber);
	}
	close(FILE);
}

sub procThisLine
{
	my ($line,$file,$passNumber)=@_;
	my $class = removeTrailingDirs($file);
	
	if ($passNumber==0) {
		if ($line=~/$ptexLabelKeyword\{([^\}]+)\}/) {
			my $tmp = $1;
			$GlobalRefs{$tmp}=removeTrailingDirs("$file:$.");
		}
		return;
	}

	if ($GlobalPtexOpen) {
		if ($line=~/$ptexRefKeyword\{([^\}]+)\}/) {
			$GlobalRefs{"HERE"} = removeTrailingDirs("$file:$.");
			
			die "Undefined reference $1\n" if (!defined($GlobalRefs{$1}));
		}
		$line=~s/$ptexRefKeyword\{([^\}]+)\}/\\verb!$GlobalRefs{$1}!/g;

		$line=~s/$ptexThisClassKeyword/$class/g;
		if ($line=~/$ptexEndKeyword/) {
			$GlobalPtexOpen=0;
			
			my $xy;
			$xy = getFunctionName() if ($passNumber>9);
			$xy = "UNDEFINED" if (!defined($xy));
			if ($xy eq "UNDEFINED") {
				my %x = (
					data => $GlobalBuffer,
					file => $file,
					line => $line,
					isInterface => $GlobalIsInterface,
				);
				$GlobalMacros{"$GlobalLabel"}= \%x;
			} else {
# 				print STDERR "Here\n";
				my $x = $GlobalMacros{"$GlobalLabel"};
				if (defined($x)) {
					my %xx = %$x;
					$xx{"function"}=$xy;
					$xx{"data"} =~ s/$ptexThisFunctionKeyword/$xy/;
					%$x=%xx;
				}
				#$GlobalMacros{"$GlobalLabel"} = \%xx;
			}

# 			print STDERR "Macro found for $GlobalLabel\n";
			$GlobalBuffer="";
			return;
		}
		$GlobalBuffer .= $line;
		return;
	}

	if ($line=~/$ptexStartKeyword +(.*$)/) {
		$GlobalLabel = $1;
# 		print STDERR "GL=$1\n";
		$GlobalLabel=~s/ //g;
		die "Empty level on line $.\n" if ($GlobalLabel eq "");
		$GlobalPtexOpen=1;
		$GlobalBuffer="";
		$GlobalIsInterface=0;
	}
	if ($line=~/$ptexInterfaceKeyword +(.*$)/) {
		$GlobalLabel = $1;
# 		print STDERR "GL=$1\n";
		$GlobalLabel=~s/ //g;
		die "Empty level on line $.\n" if ($GlobalLabel eq "");
		$GlobalPtexOpen=1;
		$GlobalBuffer="";
		$GlobalIsInterface=1;
	}
}

sub removeTrailingDirs
{
	my ($x)=@_;
	if ($x=~/\/([^\/]+$)/) {
		$x = $1;
	}
	$x=~s/\.h$//;
	return $x;
}

sub printInterface
{
	my ($thisClass)=@_;
	foreach (keys %GlobalMacros) {
		my $x = $GlobalMacros{$_};
		my %xx = %$x;
		
		my $if = $xx{"isInterface"};
# print STDERR $xx{"file"}." "."$_ $if\n";
		next if (!$if);
		my $class = removeTrailingDirs($xx{"file"});
		next unless ($class eq $thisClass);
		print $xx{"data"};
		print "\n";
	}
}

sub readFileVerbatim
{
	my ($f)=@_;
	print "\\begin{verbatim}\n";
	readFile($f);
	print "\\end{verbatim}\n";
}

sub readFile
{
	my ($f)=@_;
	open(OTHERFILE, "<", $f) or die "Cannot open file $f: $!\n";
	while() {
		print;
	}
	close(OTHERFILE);

}

sub getFunctionName
{
	my %func=();
	FunctionParsing::getNextFunction(\%func,*FILE,1);
	return $func{"name"};
}
PsimagLite-3.06/scripts/psiTag.pl000077500000000000000000000006511446452427400167740ustar00rootroot00000000000000#!/usr/bin/perl

use strict;
use warnings;
use utf8;
use lib ".";
use PsiTag;

my ($file, $label) = @ARGV;
die "USAGE: $0 file [label]\n" if (!defined($file));

my %tags;
PsiTag::main(\%tags, $file);

exit(0) if (!defined($label));

my $ptr = $tags{"$label"};

defined($ptr) or die "$0: No tag named $label\n";

my $content = $ptr->{"content"};

defined($content) or die "$0: No content for tag $label\n";

print $content;


PsimagLite-3.06/scripts/spacesIntoTabs.pl000066400000000000000000000022231446452427400204610ustar00rootroot00000000000000#!/usr/bin/perl  -w
use strict;
use Getopt::Long;

my ($file,$noerrors,$tabLength,$fix)=("YOU MUST SPECIFY -file filename",0,4,0);
defined($file) or die "$0: Needs one argument: the filename\n";
GetOptions ("ne" => \$noerrors,    # do not display errors
	"tl=s"   => \$tabLength,      #
	"fix"  => \$fix,
	"file=s"=>\$file);  # fix in place

my $fout = "tmp.txt";
open(FILE, "<", "$file") or die "Cannot open file $file: $!\n";
open(FOUT, ">", "$fout") or die "Cannot open file $fout for writing: $!\n";
while() {
	if (/^ +/) {
		my ($spaces,$tabs)=("","");
		getSpacesAndTabs($_,\$spaces,\$tabs);
		s/(^$spaces)/$tabs/;
	}
	print FOUT;
}

close(FOUT);
close(FILE);

if ($fix) {
	system("cp $file $file.bak");
	system("cp $fout $file");
}

sub getSpacesAndTabs
{
	my ($text,$spaces,$tabs)=@_;
	$text=~/(^ +)/;
	$$spaces = $1;
	my $ll = length($$spaces);
	($ll>=$tabLength) or die "$0: File $file line $. : Found $ll spaces, expected at least $tabLength\n";
	my $t = int($ll/$tabLength);
	my $r = $ll % $tabLength;
	$ll -= $r;
	$$spaces = "";
	for (my $i=0;$i<$ll;$i++) {
		$$spaces .= " ";
	}
	$$tabs = "";
	for (my $i=0;$i<$t;$i++) {
		$$tabs .= "\t";
	}
}


		
	
PsimagLite-3.06/src/000077500000000000000000000000001446452427400143035ustar00rootroot00000000000000PsimagLite-3.06/src/.clang-format000066400000000000000000000014021446452427400166530ustar00rootroot00000000000000---
# We'll use defaults from the LLVM style, but with 4 columns indentation.
BasedOnStyle: WebKit
Language: Cpp
UseTab: ForContinuationAndIndentation
TabWidth: 8
IndentWidth: 8
BreakBeforeBraces: Linux
IndentAccessModifiers: false
AccessModifierOffset: -8
EmptyLineAfterAccessModifier: Always
BraceWrapping:
  AfterCaseLabel:  true
  AfterClass:      true
  AfterControlStatement: true
  AfterEnum:       true
  AfterExternBlock: true
  AfterFunction:   true
  AfterNamespace:  true
  AfterObjCDeclaration: true
  AfterStruct:     true
  AfterUnion:      true
  AfterExternBlock: false
  BeforeCatch:     true
  BeforeElse:      true
  BeforeLambdaBody: true
  IndentBraces:    false
  SplitEmptyFunction: true
  SplitEmptyRecord: true
  SplitEmptyNamespace: true

---
PsimagLite-3.06/src/AST/000077500000000000000000000000001446452427400147325ustar00rootroot00000000000000PsimagLite-3.06/src/AST/AdditionalFunctions.h000066400000000000000000000070311446452427400210450ustar00rootroot00000000000000/*
Copyright (c) 2009-2022, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 2.]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************
*/

#ifndef ADDITIONALFUNCTIONS_H
#define ADDITIONALFUNCTIONS_H
#include "Node.h"

namespace PsimagLite
{

template 
class Modulus : public Node
{

	typedef typename VectorValueType::value_type ValueType;

public:

	Modulus* clone() const { return new Modulus(*this); }

	virtual PsimagLite::String code() const { return "%"; }

	virtual SizeType arity() const { return 2; }

	virtual ValueType exec(const VectorValueType& v) const
	{
		typedef typename Real::Type RealType;

		assert(v.size() == 2);

		RealType v0 = PsimagLite::norm(v[0]);
		RealType v1 = PsimagLite::norm(v[1]);

		SizeType x = static_cast(v0);
		SizeType y = static_cast(v1);

		ValueType result = (y == 0) ? x : x % y;
		return result;
	}

}; // class Modulus

template 
class Cosine : public Node
{

	typedef typename VectorValueType::value_type ValueType;

public:

	Cosine* clone() const { return new Cosine(*this); }

	virtual PsimagLite::String code() const { return "cos"; }

	virtual SizeType arity() const { return 1; }

	virtual ValueType exec(const VectorValueType& v) const
	{
		assert(v.size() == 1);
		return cos(v[0]);
	}
}; // class Cosine

template 
class Sine : public Node
{

	typedef typename VectorValueType::value_type ValueType;

public:

	Sine* clone() const { return new Sine(*this); }

	virtual PsimagLite::String code() const { return "sin"; }

	virtual SizeType arity() const { return 1; }

	virtual ValueType exec(const VectorValueType& v) const
	{
		assert(v.size() == 1);
		return sin(v[0]);
	}
}; // class Sine

template 
class Exp : public Node
{

	typedef typename VectorValueType::value_type ValueType;

public:

	Exp* clone() const { return new Exp(*this); }

	virtual PsimagLite::String code() const { return "exp"; }

	virtual SizeType arity() const { return 1; }

	virtual ValueType exec(const VectorValueType& v) const
	{
		assert(v.size() == 1);
		return std::exp(v[0]);
	}
}; // class Exp

template 
class TernaryOp : public Node
{

	typedef typename VectorValueType::value_type ValueType;

public:

	TernaryOp* clone() const { return new TernaryOp(*this); }

	virtual PsimagLite::String code() const { return "?"; }

	virtual SizeType arity() const { return 3; }

	virtual ValueType exec(const VectorValueType& v) const
	{
		assert(v.size() == 3);
		SizeType b = static_cast(PsimagLite::norm(v[0]));
		return (b) ? v[1] : v[2];
	}
}; // class TernaryOp

template 
class Log : public Node
{

	typedef typename VectorValueType::value_type ValueType;

public:

	Log* clone() const { return new Log(*this); }

	virtual PsimagLite::String code() const { return "log"; }

	virtual SizeType arity() const { return 1; }

	virtual ValueType exec(const VectorValueType& v) const
	{
		assert(v.size() == 1);
		return log(v[0]);
	}
}; // class Log
} // namespace PsimagLite

#endif // ADDITIONALFUNCTIONS_H
PsimagLite-3.06/src/AST/ExpressionForAST.h000066400000000000000000000043421446452427400202640ustar00rootroot00000000000000/*
Copyright (c) 2009-2022, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 2.]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************
*/
#ifndef EXPRESSIONFORAST_H
#define EXPRESSIONFORAST_H
#include "../Vector.h"
#include "Node.h"
#include "Tree.h"

namespace PsimagLite
{

template 
class ExpressionForAST
{
public:

	typedef typename PrimitivesType::VectorValueType VectorValueType;
	typedef typename VectorValueType::value_type ValueType;
	typedef Tree TreeType;
	typedef Vector::Type VectorStringType;
	typedef Node NodeType;
	typedef typename Vector::Type VectorTreeType;

	ExpressionForAST(const VectorStringType& vecStr,
	    PrimitivesType& primitives)
	{
		constexpr bool verbose = false; // FIXME
		SizeType effectiveSize = vecStr.size();
		PsimagLite::Vector::Type va;

		SizeType sumOfA = 1;
		for (SizeType i = 0; i < effectiveSize; i++) {
			PsimagLite::String cStr = vecStr[i];
			const NodeType& node = primitives.findNodeFromCode(cStr);

			SizeType a = node.arity();
			sumOfA += (a - 1);
			TreeType* tree = new TreeType(primitives, node, verbose);

			va.push_back(a);
			vecTree_.push_back(tree);
			if (sumOfA == 0)
				break;
		}

		SizeType k = 0;
		for (SizeType i = 0; i < vecTree_.size(); i++) {
			SizeType a = va[i];
			if (a == 0 || !vecTree_[i])
				continue;
			for (SizeType j = k + 1; j < k + a + 1; j++) {
				if (j >= vecTree_.size())
					continue;
				vecTree_[i]->setDescendants(*vecTree_[j]);
			}

			k += a;
		}
	}

	~ExpressionForAST()
	{
		for (SizeType i = 0; i < vecTree_.size(); i++)
			delete vecTree_[i];

		vecTree_.clear();
	}

	ValueType exec()
	{
		assert(0 < vecTree_.size());
		assert(vecTree_[0]);
		return vecTree_[0]->exec();
	}

private:

	VectorTreeType vecTree_;
}; // class ExpressionForAST

} // namespace PsimagLite
#endif // EXPRESSIONFORAST_H
PsimagLite-3.06/src/AST/Node.h000066400000000000000000000117311446452427400157730ustar00rootroot00000000000000/*
Copyright (c) 2009-2022, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 2.]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************
*/
#ifndef PSI_NODE_H
#define PSI_NODE_H
#include "../Vector.h"
#include 

namespace PsimagLite
{

template 
class Node
{

public:

	typedef AnglesType_ AnglesType;
	typedef typename VectorValueType::value_type ValueType;
	typedef typename PsimagLite::Vector::Type VectorAnglesType;

	virtual ~Node() { }

	virtual Node* clone() const = 0;

	virtual PsimagLite::String code() const = 0;

	virtual SizeType arity() const = 0;

	virtual ValueType exec(const VectorValueType&) const = 0;

	virtual ValueType exec(const VectorValueType&,
	    const VectorAnglesType*,
	    SizeType&) const
	{
		throw PsimagLite::RuntimeError("node::exec() long form\n");
	}

	virtual void set(const ValueType&) const
	{
		throw PsimagLite::RuntimeError("node::set\n");
	}

	virtual void setAngle(PsimagLite::String) const { }

	virtual void print(std::ostream&) const { }

	virtual void setDcValue(const ValueType&) const
	{
		throw PsimagLite::RuntimeError("node::setDcValue\n");
	}

	virtual bool isInput() const { return false; }

}; // class Node

template 
class Plus : public Node
{

	typedef typename VectorValueType::value_type ValueType;

public:

	Plus* clone() const { return new Plus(*this); }

	virtual PsimagLite::String code() const { return "+"; }

	virtual SizeType arity() const { return 2; }

	virtual ValueType exec(const VectorValueType& v) const
	{
		assert(v.size() == 2);
		return v[0] + v[1];
	}

}; // class Plus

template 
class Minus : public Node
{

	typedef typename VectorValueType::value_type ValueType;

public:

	Minus* clone() const { return new Minus(*this); }

	virtual PsimagLite::String code() const { return "-"; }

	virtual SizeType arity() const { return 2; }

	virtual ValueType exec(const VectorValueType& v) const
	{
		assert(v.size() == 2);
		return v[0] - v[1];
	}

}; // class Minus

template 
class Times : public Node
{

	typedef typename VectorValueType::value_type ValueType;

public:

	Times* clone() const { return new Times(*this); }

	virtual PsimagLite::String code() const { return "*"; }

	virtual SizeType arity() const { return 2; }

	virtual ValueType exec(const VectorValueType& v) const
	{
		assert(v.size() == 2);
		return v[0] * v[1];
	}

}; // class Times

template 
class DividedBy : public Node
{

	typedef typename VectorValueType::value_type ValueType;

public:

	DividedBy* clone() const { return new DividedBy(*this); }

	virtual PsimagLite::String code() const { return "/"; }

	virtual SizeType arity() const { return 2; }

	virtual ValueType exec(const VectorValueType& v) const
	{
		assert(v.size() == 2);
		if (std::fabs(v[1]) < 1e-6)
			return v[0];

		return v[0] / v[1];
	}

}; // class DividedBy

template 
class IfGtZero : public Node
{

	typedef typename VectorValueType::value_type ValueType;

public:

	IfGtZero* clone() const { return new IfGtZero(*this); }

	virtual char code() const { return 'g'; }

	virtual SizeType arity() const { return 1; }

	virtual ValueType exec(const VectorValueType& v) const
	{
		assert(v.size() == 1);

		return (v[0] > 0) ? 1 : 0;
	}

}; // class IfGtZero

template 
class Int : public Node
{

	typedef typename VectorValueType::value_type ValueType;

public:

	Int* clone() const { return new Int(*this); }

	virtual char code() const { return 'i'; }

	virtual SizeType arity() const { return 1; }

	virtual ValueType exec(const VectorValueType& v) const
	{
		assert(v.size() == 1);

		SizeType x = static_cast(v[0]);
		return x;
	}

}; // class Int

template 
class Input : public Node
{

	typedef typename VectorValueType::value_type ValueType;

public:

	Input(SizeType i)
	    : char_(i + 48)
	    , strOneChar_(" ")
	{
		strOneChar_[0] = char_;
	}

	Input* clone() const { return new Input(*this); }

	virtual PsimagLite::String code() const { return strOneChar_; }

	virtual SizeType arity() const { return 0; }

	virtual ValueType exec(const VectorValueType& v) const
	{
		assert(v.size() == 0);
		return input_;
	}

	virtual void set(const ValueType& x) const { input_ = x; }

	virtual bool isInput() const { return true; }

private:

	char char_;
	PsimagLite::String strOneChar_;
	mutable ValueType input_;

}; // class Input

} // namespace PsimagLite
#endif // PSI_NODE_H
PsimagLite-3.06/src/AST/PlusMinusMultiplyDivide.h000066400000000000000000000057571446452427400217450ustar00rootroot00000000000000/*
Copyright (c) 2009-2022, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 2.]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************
*/
#ifndef PSI_LUS_MINUS_MULT_DIV_H
#define PSI_LUS_MINUS_MULT_DIV_H
#include "../PsimagLite.h"
#include "../Vector.h"
#include "AdditionalFunctions.h"
#include "Node.h"
#include 

namespace PsimagLite
{

template 
class PlusMinusMultiplyDivide
{

public:

	typedef typename PsimagLite::Vector::Type VectorValueType;
	typedef Node NodeType;
	typedef typename PsimagLite::Vector::Type VectorNodeType;
	typedef Plus PlusType;
	typedef Minus MinusType;
	typedef Times TimesType;
	typedef DividedBy DividedByType;
	typedef Modulus ModulusType;
	typedef Input InputType;
	typedef ValueType_ ValueType;
	typedef PsimagLite::Vector::Type VectorStringType;
	typedef PsimagLite::Vector::Type VectorSizeType;

	PlusMinusMultiplyDivide()
	    : inputsSoFar_(0)
	{
		NodeType* plus = new PlusType();
		nodes_.push_back(plus);

		NodeType* minus = new MinusType();
		nodes_.push_back(minus);

		NodeType* times = new TimesType();
		nodes_.push_back(times);

		NodeType* dividedBy = new DividedByType();
		nodes_.push_back(dividedBy);

		NodeType* modulus = new ModulusType();
		nodes_.push_back(modulus);

		NodeType* sine = new Sine();
		nodes_.push_back(sine);

		NodeType* cosine = new Cosine();
		nodes_.push_back(cosine);

		NodeType* log = new Log();
		nodes_.push_back(log);

		NodeType* exp = new Exp();
		nodes_.push_back(exp);

		NodeType* ternary = new TernaryOp();
		nodes_.push_back(ternary);
	}

	~PlusMinusMultiplyDivide()
	{
		for (SizeType i = 0; i < nodes_.size(); i++)
			delete nodes_[i];

		nodes_.clear();
	}

	const VectorNodeType& nodesSerial() const { return nodes_; }

	const NodeType& findNodeFromCode(const String& code)
	{
		SizeType n = nodes_.size();
		for (SizeType i = 0; i < n; ++i) {
			if (nodes_[i]->isInput())
				continue;
			if (nodes_[i]->code() == code)
				return *nodes_[i];
		}

		// Assume it's an input
		NodeType* input = new InputType(inputsSoFar_++);

		try {
			input->set(PsimagLite::atof(code));
		} catch (std::exception&) {
			throw RuntimeError("FATAL: No function with code " + code + " was found.\n");
		}

		nodes_.push_back(input);
		return *input;
	}

private:

	VectorNodeType nodes_;
	SizeType inputsSoFar_;
}; // class PlusMinusMultiplyDivide

} // namespace PsimagLite

#endif // PSI_LUS_MINUS_MULT_DIV_H
PsimagLite-3.06/src/AST/Tree.h000066400000000000000000000053311446452427400160040ustar00rootroot00000000000000/*
Copyright (c) 2009-2022, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 2.]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************
*/

#ifndef PSI_TREE_H
#define PSI_TREE_H
#include "../PsimagLite.h"

namespace PsimagLite
{

template 
class Tree
{

public:

	typedef Tree TreeType;
	typedef typename PrimitivesType::ValueType ValueType;
	typedef typename PrimitivesType::NodeType NodeType;
	typedef
	    typename PsimagLite::Vector::Type VectorTreeType;
	typedef typename NodeType::AnglesType AnglesType;
	typedef typename PsimagLite::Vector::Type VectorAnglesType;
	typedef typename PsimagLite::Vector::Type VectorValueType;

	Tree(const PrimitivesType& primitives, const NodeType& node, bool verbose)
	    : primitives_(primitives)
	    , node_(node)
	    , verbose_(verbose)
	{
	}

	~Tree() { }

	ValueType exec() const
	{
		if (verbose_)
			std::cout << " type= " << node_.code() << "\n";
		VectorValueType values(descendants_.size());

		for (SizeType i = 0; i < descendants_.size(); i++) {
			values[i] = descendants_[i]->exec();
		}

		//		for (SizeType i = 0; i < values.size(); i++) {
		//			if (values[i]<0 || values[i]==0 ||
		// values[i] >0) continue; 			throw
		// std::runtime_error("exec\n");
		//		}

		ValueType tmp = node_.exec(values);
		if (verbose_) {
			std::cout << "tmp= " << tmp
				  << " type= " << node_.code();
			for (SizeType i = 0; i < values.size(); i++)
				std::cout << values[i] << " ";
			std::cout << "\n";
		}

		return tmp;
	}

	void set(const VectorValueType& values) const
	{
		for (SizeType i = 0; i < descendants_.size(); i++)
			descendants_[i]->set(values);

		const PsimagLite::String str = node_.code();
		if (str.length() == 0)
			err("Node with empty code!?\n");

		if (str.length() > 1)
			return;
		const char c = str[0];
		if (c < 48 || c > 57)
			return;
		SizeType index = c - 48;
		assert(index < values.size());
		node_.set(values[index]);
	}

	void setDescendants(const TreeType& n0) { descendants_.push_back(&n0); }

	void setDescendants(const TreeType& n0, const TreeType& n1)
	{
		descendants_.push_back(&n0);
		descendants_.push_back(&n1);
	}

private:

	Tree& operator=(const Tree&) = delete;

	const PrimitivesType& primitives_;
	const NodeType& node_;
	bool verbose_;
	VectorTreeType descendants_;
};

} // namespace PsimagLite

#endif // PSI_TREE_H
PsimagLite-3.06/src/Ainur/000077500000000000000000000000001446452427400153615ustar00rootroot00000000000000PsimagLite-3.06/src/Ainur/Ainur.h000066400000000000000000000002111446452427400166020ustar00rootroot00000000000000#ifndef _AINUR_H_
#define _AINUR_H_

#ifdef USE_BOOST
#include "AinurSpirit.h"
#else
#include "AinurEmpty.h"
#endif

#endif // _AINUR_H_
PsimagLite-3.06/src/Ainur/AinurComplex.hh000066400000000000000000000034751446452427400203210ustar00rootroot00000000000000#ifndef AINURCOMPLEX_HH
#define AINURCOMPLEX_HH

#include "../PsimagLite.h"

namespace PsimagLite
{

struct AinurComplex {

	static void convert(long unsigned int& t, std::string str)
	{
		t = PsimagLite::atoi(str);
	}

	static void convert(unsigned int& t, std::string str)
	{
		t = PsimagLite::atoi(str);
	}

	static void convert(long int& t, std::string str)
	{
		t = PsimagLite::atoi(str);
	}

	static void convert(int& t, std::string str)
	{
		t = PsimagLite::atoi(str);
	}

	static void convert(double& t, std::string str)
	{
		t = PsimagLite::atof(str);
	}

	static void convert(float& t, std::string str)
	{
		t = PsimagLite::atof(str);
	}

	template 
	static void convert(std::complex& t, std::string str)
	{
		t = toComplex(str);
	}

	static void convert(String& t, std::string str) { t = str; }

	template 
	static void convert(T& t, std::string str)
	{
		String msg("Unknown type ");
		throw RuntimeError("convert(): " + msg + typeid(t).name() + " for " + str + "\n");
	}

private:

	template 
	static std::complex toComplex(std::string str)
	{
		typedef std::complex ComplexType;

		if (str == "i")
			return ComplexType(0., 1.);
		if (str == "-i")
			return ComplexType(0., -1.);

		String buffer;
		bool flag = false;
		const SizeType n = str.length();
		RealType real1 = 0;
		for (SizeType i = 0; i < n; ++i) {
			bool isSqrtMinus1 = (str[i] == 'i');
			if (isSqrtMinus1 && flag)
				throw RuntimeError("Error parsing number " + str + "\n");

			if (isSqrtMinus1) {
				flag = true;
				real1 = (buffer == "") ? 0 : atof(buffer.c_str());
				buffer = "";
				continue;
			}

			buffer += str[i];
		}

		return (flag) ? ComplexType(real1, atof(buffer.c_str()))
			      : ComplexType(atof(buffer.c_str()), 0);
	}
};

} // namespace PsimagLite
#endif // AINURCOMPLEX_HH
PsimagLite-3.06/src/Ainur/AinurConvert.cpp000066400000000000000000000000651446452427400205050ustar00rootroot00000000000000#ifdef USE_BOOST
#include "AinurConvert1.cpp"
#endif
PsimagLite-3.06/src/Ainur/AinurConvert.hh000066400000000000000000000060451446452427400203260ustar00rootroot00000000000000#ifndef AINURCONVERT_HH
#define AINURCONVERT_HH
#include "../Matrix.h"
#include "../PsimagLite.h"
#include "AinurMacros.hh"

namespace PsimagLite
{

struct AinurVariable {
	std::string key;
	std::string value;
	std::string type;
	std::string opaque;
};

class AinurConvert
{

	template 
	struct Action {

		Action(String name, std::vector& t, const AinurMacros& ainurMacros)
		    : name_(name)
		    , t_(t)
		    , ainurMacros_(ainurMacros)
		{
		}

		template 
		void operator()(A& attr, ContextType&, bool&) const;

	private:

		String name_;
		std::vector& t_;
		const AinurMacros& ainurMacros_;
	}; // struct Action

	template 
	struct ActionMatrix {

		ActionMatrix(String name, Matrix& t, const AinurMacros& ainurMacros)
		    : name_(name)
		    , t_(t)
		    , ainurMacros_(ainurMacros)
		{
		}

		template 
		void operator()(A& attr, ContextType&, bool&) const;

	private:

		String name_;
		Matrix& t_;
		const AinurMacros& ainurMacros_;
	}; // struct ActionMatrix

public:

	AinurConvert(const AinurMacros& ainurMacros)
	    : ainurMacros_(ainurMacros)
	{
	}

	template 
	void convert(std::vector& t, const AinurVariable& ainurVariable, typename EnableIf::isArith || IsComplexNumber::True || TypesEqual::True, int>::Type = 0);

	template 
	void convert(Matrix& t, const AinurVariable& ainurVariable);

	template 
	void convert(
	    T& t,
	    const AinurVariable& ainurVariable,
	    typename EnableIf::isIntegral, int>::Type = 0)
	{
		String label = ainurMacros_.valueFromFunction(ainurVariable.value);

		try {
			t = PsimagLite::atoi(label.c_str());
		} catch (std::exception& e) {
			std::cerr << "FATAL: AinurState: Label " + label + " must be an integer\n";
			throw e.what();
		}
	}

	template 
	void
	convert(T& t, const AinurVariable& ainurVariable, typename EnableIf::isFloat, int>::Type = 0)
	{
		String label = ainurMacros_.valueFromFunction(ainurVariable.value);

		try {
			t = PsimagLite::atof(label.c_str());
		} catch (...) {
			err("FATAL: AinurState: Label " + label + " must be a real number\n");
		}
	}

	void convert(String& t, const AinurVariable& ainurVariable)
	{
		String label = ainurMacros_.valueFromFunction(ainurVariable.value);
		SizeType l = label.size();
		if (l > 1 && label[0] == '"' && label[l - 1] == '"') {
			t = (l == 2) ? "" : label.substr(1, l - 2);
			return;
		}

		t = label;
	}

private:

	static String stringContext(std::string::iterator it,
	    std::string::iterator start,
	    std::string::iterator end,
	    SizeType before = 5,
	    SizeType after = 10)
	{
		std::string::iterator alpha = it;
		SizeType counter = 0;
		while (alpha != start && counter++ < before)
			--alpha;

		std::string::iterator omega = it;
		counter = 0;
		while (omega != end && counter++ < after)
			++omega;

		return String(alpha, omega);
	}

	const AinurMacros& ainurMacros_;
};
} // namespace PsimagLite
#endif // AINURCONVERT_HH
PsimagLite-3.06/src/Ainur/AinurConvert1.cpp000066400000000000000000000113521446452427400205670ustar00rootroot00000000000000#include "AinurComplex.hh"
#include "AinurConvert.hh"
#include "AinurDoubleOrFloat.h"
#include 
#include 
#include 
#include 

namespace PsimagLite
{

boost::spirit::qi::rule(), boost::spirit::qi::space_type>
ruleRows()
{
	boost::spirit::qi::rule(),
	    boost::spirit::qi::space_type>
	    myrule = "[" >> (+~boost::spirit::qi::char_(",[]")) % ',' >> "]";
	return myrule;
}

template 
template 
void AinurConvert::ActionMatrix::operator()(A& attr, ContextType&, bool&) const
{
	SizeType rows = attr.size();
	if (rows == 0)
		return;
	SizeType cols = attr[0].size();
	t_.resize(rows, cols);
	for (SizeType i = 0; i < rows; ++i) {
		if (attr[i].size() != cols)
			err("Ainur: Problem reading matrix\n");
		for (SizeType j = 0; j < cols; ++j) {
			String attrAfter = ainurMacros_.valueFromFunction(attr[i][j]);
			AinurComplex::convert(t_(i, j), attrAfter);
		}
	}
}

//---------

template 
template 
void AinurConvert::Action::operator()(A& attr, ContextType&, bool&) const
{
	const SizeType n = attr.size();
	if (n == 2 && attr[1] == "...") {
		const SizeType m = t_.size();
		if (m == 0)
			err("Cannot use ellipsis for vector of unknown size\n");
		AinurComplex::convert(t_[0], attr[0]);
		for (SizeType i = 1; i < m; ++i)
			t_[i] = t_[0];
		return;
	}

	if (n == 2 && attr[1].length() > 4 && attr[1].substr(0, 4) == "...x") {
		const SizeType m = t_.size();
		const SizeType l = attr[1].length();
		const SizeType mm = PsimagLite::atoi(attr[1].substr(4, l - 4));
		if (m != 0)
			std::cout << "Resizing vector to " << mm << "\n";
		t_.resize(mm);
		AinurComplex::convert(t_[0], attr[0]);
		for (SizeType i = 1; i < mm; ++i)
			t_[i] = t_[0];
		return;
	}

	t_.resize(n);
	for (SizeType i = 0; i < n; ++i) {
		String val = ainurMacros_.valueFromFunction(attr[i]);
		AinurComplex::convert(t_[i], val);
	}
}

//---------

template 
void AinurConvert::convert(Matrix& t, const AinurVariable& ainurVariable)
{
	namespace qi = boost::spirit::qi;
	typedef std::string::iterator IteratorType;
	typedef std::vector VectorStringType;
	typedef std::vector VectorVectorVectorType;

	String value = ainurVariable.value;

	IteratorType it = value.begin();
	qi::rule ruRows = ruleRows();

	qi::rule full = "[" >> -(ruRows % ",") >> "]";

	ActionMatrix actionMatrix("matrix", t, ainurMacros_);
	bool r = qi::phrase_parse(it, value.end(), full[actionMatrix], qi::space);

	// check if we have a match
	if (!r) {
		err("matrix parsing failed near " + stringContext(it, value.begin(), value.end()) + "\n");
	}

	if (it != value.end())
		std::cerr << "matrix parsing: unmatched part exists\n";
}

template 
void AinurConvert::convert(std::vector& t,
    const AinurVariable& ainurVariable,
    typename EnableIf::isArith || IsComplexNumber::True || TypesEqual::True,
	int>::Type)
{
	namespace qi = boost::spirit::qi;
	typedef std::string::iterator IteratorType;
	typedef std::vector VectorStringType;

	String value = ainurVariable.value;
	IteratorType it = value.begin();
	qi::rule ruRows = ruleRows();

	Action actionRows("rows", t, ainurMacros_);

	bool r = qi::phrase_parse(it, value.end(), ruRows[actionRows], qi::space);

	// check if we have a match
	if (!r)
		err("vector parsing failed near " + stringContext(it, value.begin(), value.end()) + "\n");

	if (it != value.end()) {
		std::cerr << "vector parsing: unmatched part exists near ";
		std::cerr << stringContext(it, value.begin(), value.end())
			  << "\n";
	}
}

//---------

template void AinurConvert::convert(Matrix&,
    const AinurVariable&);

template void AinurConvert::convert(Matrix>&,
    const AinurVariable&);

template void AinurConvert::convert(Matrix&, const AinurVariable&);

template void AinurConvert::convert(std::vector&,
    const AinurVariable&,
    int);

template void
AinurConvert::convert(std::vector>&,
    const AinurVariable&,
    int);

template void AinurConvert::convert(std::vector&,
    const AinurVariable&,
    int);

template void AinurConvert::convert(std::vector&, const AinurVariable&, int);

template void AinurConvert::convert(std::vector&,
    const AinurVariable&,
    int);
} // namespace PsimagLite
PsimagLite-3.06/src/Ainur/AinurDoubleOrFloat.h000066400000000000000000000004731446452427400212360ustar00rootroot00000000000000#ifndef AINURDOUBLEORFLOAT_H
#define AINURDOUBLEORFLOAT_H

namespace PsimagLite
{

#ifdef USE_FLOAT
#define DoubleOrFloatType float
#define DoubleOrFloatUnderscore float_
#else
#define DoubleOrFloatType double
#define DoubleOrFloatUnderscore double_
#endif

} // namespace PsimagLite
#endif // AINURDOUBLEORFLOAT_H
PsimagLite-3.06/src/Ainur/AinurEmpty.h000066400000000000000000000017051446452427400176320ustar00rootroot00000000000000#ifndef _AINUR_EMPTY_H_
#define _AINUR_EMPTY_H_
#include "PsimagLite.h"
#include "TypeToString.h"
#include "Vector.h"
#include 
#include 

namespace PsimagLite
{

class Ainur
{

public:

	Ainur(String str)
	    : dummy_("")
	{
		errorMessage();
	}

	String& prefix() { return dummy_; }

	const String& prefix() const { return dummy_; }

	void printUnused(std::ostream& os) const { errorMessage(); }

	void printAll(std::ostream& os) const { errorMessage(); }

	template 
	void readValue(SomeType& t, String label) const
	{
		errorMessage();
	}

	std::string resolve(const std::string& str) const
	{
		errorMessage();
		return "";
	}

	template 
	void setMap(SomeMapType&) const
	{
		errorMessage();
	}

private:

	void errorMessage() const
	{
		err("To use Ainur, you need boost-devel, and compile with "
		    "-DUSE_BOOST\n");
	}

	String dummy_;
};

} // namespace PsimagLite
#endif // _AINUR_EMPTY_H_
PsimagLite-3.06/src/Ainur/AinurLexical.h000066400000000000000000000024061446452427400201140ustar00rootroot00000000000000#ifndef AINURLEXICAL_H
#define AINURLEXICAL_H
#include "../PsimagLite.h"
#include "../Vector.h"

/* This class only checks whether input file contains valid characters
 * and throws if not */
namespace PsimagLite
{

class AinurLexical
{

public:

	AinurLexical(const String& str)
	{
		for (String::const_iterator it = str.begin(); it != str.end();
		     ++it) {
			if (allowedChar(*it))
				continue;
			unsigned int x = *it;
			err("Lexical error: Not allowed char with code " + ttos(x) + " near " + getContext(it, str.begin(), str.end()) + "\n");
		}
	}

	bool static isEmptyChar(char c)
	{
		return (isWhitespace(c) || isEOL(c));
	}

private:

	String getContext(String::const_iterator c, String::const_iterator b, String::const_iterator e, SizeType n = 10) const
	{
		String::const_iterator begin = (c - n > b) ? c - n : b;
		String::const_iterator end = (c + n > e) ? e : c + n;

		return String(begin, end);
	}

	static bool allowedChar(unsigned char c)
	{
		if (isWhitespace(c) || isEOL(c))
			return true;
		return (c < 33 || c > 126 || c == 96) ? false : true;
	}

	static bool isWhitespace(char c) { return (c == ' ' || c == '\t'); }

	static bool isEOL(char c) { return (c == '\n' || c == '\r'); }
}; // class AinurLexical
} // namespace PsimagLite
#endif // AINURLEXICAL_H
PsimagLite-3.06/src/Ainur/AinurMacros.hh000066400000000000000000000142121446452427400201250ustar00rootroot00000000000000#ifndef AINURMACROS_HH
#define AINURMACROS_HH
#include "../PsimagLite.h"
#include 
#include 

namespace PsimagLite
{

class AinurMacros
{

public:

	struct NativeMacro {
		std::string type;
		std::string name;
		std::string value;
	};

	class AinurFunction
	{

		static constexpr SizeType MAX_LINE = 2048;

	public:

		AinurFunction(const std::string& args)
		    : separator_("space")
		    , columnX_(0)
		    , columnY_(1)
		{
			std::string csl = deleteEnclosing(args, '(', ')');
			std::vector tokens;
			split(tokens, csl, ",");
			if (tokens.size() == 0) {
				throw RuntimeError(
				    "Parse error for " + args + ". Expected (filename, separator, "
								"column_x, column_y),"
				    + " where separator and columns are "
				      "optional.\n");
			}

			filename_ = deleteEnclosing(tokens[0], '\"');
			if (tokens.size() > 1) {
				separator_ = tokens[1];
			}

			separatorForSplit_ = setSeparatorForSplit(separator_);

			if (tokens.size() > 2) {
				columnX_ = PsimagLite::atoi(tokens[2]);
			}

			if (tokens.size() > 3) {
				columnY_ = PsimagLite::atoi(tokens[3]);
			}

			if (tokens.size() > 4) {
				throw RuntimeError("Parse error for " + args + ": too many arguments\n");
			}

			readData();
		}

		const double& operator()(const double& x) const
		{
			auto it = std::find_if(
			    data_.begin(), data_.end(), [&x](const std::pair& pair) {
				    return (pair.first == x);
			    });
			return it->second;
		}

		static std::string deleteEnclosing(const std::string& content,
		    char b)
		{
			return deleteEnclosing(content, b, b);
		}

		static std::string deleteEnclosing(const std::string& content,
		    char b,
		    char e)
		{
			SizeType length = content.size();
			if (length == 0)
				return content;
			SizeType last = length - 1;
			SizeType total = length;
			SizeType start = 0;

			if (content[0] == b) {
				start = 1;
				--total;
			}

			if (last > 0 && content[last] == e) {
				--total;
			}

			return content.substr(start, total);
		}

	private:

		static std::string
		setSeparatorForSplit(const std::string& separator)
		{
			if (separator == "space") {
				return " ";
			} else if (separator == "comma") {
				return ",";
			}

			throw RuntimeError("Wrong separator" + separator + ": only space and comma allowed.\n");
		}

		static bool emptyLine(const std::string& s)
		{
			for (SizeType i = 0; i < s.size(); ++i) {
				if (s[i] != ' ' || s[i] != '\t')
					return false;
			}

			return true;
		}
		void readData()
		{
			std::ifstream fin(filename_);
			if (!fin || !fin.good() || fin.bad()) {
				throw RuntimeError("Could not open " + filename_ + "\n");
			}

			char s[MAX_LINE];
			while (!fin.eof()) {
				fin.getline(s, MAX_LINE);
				if (emptyLine(std::string(s)))
					continue;
				std::vector tokens;
				split(tokens, s);
				if (columnX_ > tokens.size() || columnY_ > tokens.size()) {
					throw RuntimeError("Line too small: " + std::string(s) + "\n");
				}

				double vx = PsimagLite::atof(tokens[columnX_]);
				double vy = PsimagLite::atof(tokens[columnY_]);
				std::pair pair(vx, vy);
				data_.emplace_back(pair);
			}
		}

		std::string filename_;
		std::string separator_;
		std::string separatorForSplit_;
		SizeType columnX_;
		SizeType columnY_;
		std::vector> data_;
	};

	AinurMacros()
	    : AINUR_FROM_FILE("AinurFromFile")
	{
		nativeMacros_.push_back(
		    { "function", AINUR_FROM_FILE, "!" + AINUR_FROM_FILE });
	}

	SizeType total() const { return nativeMacros_.size(); }

	const NativeMacro& nativeMacro(SizeType ind) const
	{
		assert(ind < nativeMacros_.size());
		return nativeMacros_[ind];
	}

	std::string procNativeMacro(const std::string& line)
	{
		if (line.substr(1, AINUR_FROM_FILE.size()) == AINUR_FROM_FILE) {
			SizeType start = AINUR_FROM_FILE.size() + 1;
			SizeType len = line.size();
			assert(len > start);
			SizeType rest = len - start;
			std::string content = line.substr(start, rest);
			return addAinurFromFile(content);
		}

		throw RuntimeError("Unknown native macro for " + line + "\n");
	}

	// Expect ("function.txt") or
	// ("function.txt")(3.0)
	std::string valueFromFunction(const std::string& line) const
	{
		std::pair nameValue = getFunctionNameValue(line);

		if (nameValue.second == "") {
			return nameValue.first;
		}

		if (!isAfloat(nameValue.second)) {
			return line;
		}

		// return value
		std::string functionName = nameValue.first;

		// using and defining in same line not allowed
		if (functionNameToIndex_.count(functionName) == 0) {
			throw RuntimeError("valueFromFunction: " + functionName + " undefined.\n");
		}

		SizeType index = functionNameToIndex_.at(functionName);
		assert(index < ainurFunctions_.size());
		std::string argument = AinurFunction::deleteEnclosing(nameValue.second, '(', ')');
		double x = PsimagLite::atof(argument);
		double y = ainurFunctions_[index](x);
		return std::to_string(y);
	}

private:

	// Expect ("function.txt") or
	// ("function.txt")(3.0)
	static std::pair
	getFunctionNameValue(const std::string& line)
	{
		SizeType length = line.size();
		if (length < 4) {
			return std::pair(line, "");
		}

		SizeType last = length - 1;

		if (line[0] != '(' || line[last] != ')') {
			return std::pair(line, "");
		}

		SizeType i = 1;
		for (; i < line.size(); ++i) {
			if (line[i] == ')' && line[i + 1] == '(')
				break;
		}

		// no value found
		if (i == line.size()) {
			return std::pair(line, "");
		}

		return std::pair(
		    line.substr(0, i + 1), line.substr(i + 2, length - i - 3));
	}

	std::string addAinurFromFile(const std::string& content)
	{
		// Uniqueness
		if (functionNameToIndex_.count(content) == 0) {
			functionNameToIndex_[content] = ainurFunctions_.size();
			AinurFunction ainurFunction(content);
			ainurFunctions_.emplace_back(ainurFunction);
		}

		return content;
	}

	const std::string AINUR_FROM_FILE;
	std::vector nativeMacros_;
	std::map functionNameToIndex_;
	std::vector ainurFunctions_;
};

} // namespace PsimagLite
#endif // AINURMACROS_HH
PsimagLite-3.06/src/Ainur/AinurReadable.h000066400000000000000000000134331446452427400202340ustar00rootroot00000000000000#ifndef AINURREADABLE_H
#define AINURREADABLE_H
#include "AinurDoubleOrFloat.h"
#include "AinurStore.h"

namespace PsimagLite
{

class AinurReadable
{

public:

	typedef Store StoreType;
	typedef Vector::Type VectorStoreType;
	typedef StoreType::AinurLexicalType AinurLexicalType;
	typedef AinurLexicalType::VectorStringType VectorStringType;
	typedef DoubleOrFloatType RealType;
	typedef std::complex ComplexType;

	AinurReadable(const VectorStringType& names,
	    const VectorStoreType& storage)
	    : names_(names)
	    , storage_(storage)
	{
	}

	int storageIndexByName(String name) const
	{
		VectorStringType::const_iterator it = std::find(names_.begin(), names_.end(), name);
		if (it == names_.end())
			return -1;
		return it - names_.begin();
	}

	String& prefix() { return prefix_; }

	const String& prefix() const { return prefix_; }

	void printUnused(std::ostream& os) const
	{
		SizeType n = storage_.size();
		for (SizeType i = 0; i < n; ++i) {
			if (storage_[i].used() > 0 || storage_[i].valueSize() == 0)
				continue;
			assert(i < names_.size());
			os << "WARNING: Unused label " << names_[i] << "\n";
		}
	}

	void readValue(long int& t, String s) const
	{
		int t2 = 0;
		readValue(t2, s);
		t = t2;
	}

	void readValue(SizeType& t, String s) const
	{
		int t2 = 0;
		readValue(t2, s);
		t = t2;
	}

	void readValue(int& t, String s) const
	{
		s = prefix_ + s;
		int x = storageIndexByName(s);
		if (x < 0)
			err("Not found " + s + "\n");
		const Store& store = storage_[x];
		if (store.type() != Store::SCALAR && store.subType() != Store::INTEGER)
			err("In input, " + s + " must be an integer\n");
		store.increaseUsage();
		t = atoi(store.value(0, names_[x]).c_str());
	}

	void readValue(RealType& t, String s) const
	{
		s = prefix_ + s;
		int x = storageIndexByName(s);
		if (x < 0)
			err("Not found " + s + "\n");
		const Store& store = storage_[x];
		if (store.type() != Store::SCALAR && store.subType() != Store::REAL)
			err("In input, " + s + " must be a real\n");
		store.increaseUsage();
		t = atof(store.value(0, names_[x]).c_str());
	}

	void readValue(String& t, String s) const
	{
		s = prefix_ + s;
		int x = storageIndexByName(s);
		if (x < 0)
			err("Not found " + s + "\n");
		const Store& store = storage_[x];
		if (store.type() != Store::SCALAR && store.subType() != Store::STRING)
			err("In input, " + s + " must be a string\n");
		store.increaseUsage();
		t = store.value(0, names_[x]);
	}

	// read vectors
	template 
	typename EnableIf::True, void>::Type
	readValue(VectorLikeType& v, String sOrig) const
	{
		String s = prefix_ + sOrig;
		int x = storageIndexByName(s);
		if (x < 0)
			err("Not found " + s + "\n");

		const Store& store = storage_[x];

		if (store.type() == Store::MATRIX) {
			std::cerr << "readValue: " << s
				  << " coerced into vector\n";
			Matrix m;
			readValue(m, sOrig);
			v = m.data();
			return;
		}

		if (store.type() != Store::VECTOR)
			err("In input, " + s + " must be a vector\n");

		SizeType n = store.valueSize();

		if (n == 0)
			err("In input, vector " + s + " has 0 entries\n");

		store.increaseUsage();

		String tmp = (n == 2) ? store.value(1, names_[x]) : "";
		AinurLexicalType::removeTrailingBlanks(tmp);
		size_t start = tmp.find("...");
		SizeType times = (start != String::npos && tmp.length() > 3)
		    ? atoi(tmp.substr(start + 3, tmp.length() - 3).c_str())
		    : 0;

		if (n == 2 && start != String::npos) {
			assert(static_cast(x) < names_.size());
			if (v.size() < 3 && times == 0)
				err("Ellipsis cannot be used for this "
				    "vector, "
				    + names_[x] + "\n");
			if (times > 0)
				v.resize(times);
			n = v.size();
			for (SizeType i = 0; i < n; ++i)
				getEntryFromString(v[i],
				    store.value(0, names_[x]));
			return;
		}

		if (v.size() != n) {
			v.clear();
			v.resize(n);
		}

		for (SizeType i = 0; i < n; ++i)
			getEntryFromString(v[i], store.value(i, names_[x]));
	}

	// read matrices
	template 
	typename EnableIf::isArith, void>::Type
	readValue(Matrix& m, String s) const
	{
		s = prefix_ + s;
		int x = storageIndexByName(s);
		if (x < 0)
			err("Not found " + s + "\n");
		const Store& store = storage_[x];
		if (store.type() != Store::MATRIX)
			err("In input, " + s + " must be a matrix\n");
		store.increaseUsage();
		SizeType n = store.valueSize();
		if (n < 2)
			err("In input, matrix " + s + " internal storage error I\n");

		store.increaseUsage();

		SizeType rows = atoi(store.value(0, names_[x]).c_str());
		SizeType cols = atoi(store.value(1, names_[x]).c_str());

		m.clear();
		if (rows == 0 && cols == 0)
			return;
		if (rows * cols == 0)
			err("Matrix with one of {rows, cols} 0 must have both "
			    "0\n");

		m.resize(rows, cols);

		if (rows * cols + 2 != n)
			err("In input, matrix " + s + " internal storage error II\n");

		for (SizeType i = 0; i < rows; ++i)
			for (SizeType j = 0; j < cols; ++j)
				getEntryFromString(
				    m(i, j),
				    store.value(i + j * rows + 2, names_[x]));
	}

	// read matrices
	template 
	typename EnableIf::isFloat, void>::Type
	readValue(Matrix>& m, String s) const
	{
		err("AinurReadable: Complex matrices not implemented\n");
	}

private:

	void getEntryFromString(SizeType& entry, String s) const
	{
		entry = atoi(s.c_str());
	}

	void getEntryFromString(RealType& entry, String s) const
	{
		entry = atof(s.c_str());
	}

	void getEntryFromString(ComplexType& entry, String s) const
	{
		err("getEntryFromString not implemented for complex\n");
	}

	const VectorStringType& names_;
	const VectorStoreType& storage_;
	String prefix_;
}; // class AinurReadable

} // namespace PsimagLite
#endif // AINURREADABLE_H
PsimagLite-3.06/src/Ainur/AinurSpirit.cpp000066400000000000000000000000641446452427400203360ustar00rootroot00000000000000#ifdef USE_BOOST
#include "AinurSpirit1.cpp"
#endif
PsimagLite-3.06/src/Ainur/AinurSpirit.h000066400000000000000000000040141446452427400200020ustar00rootroot00000000000000#ifndef _AINUR_SPIRIT_H_
#define _AINUR_SPIRIT_H_
#include "../PsimagLite.h"
#include "../TypeToString.h"
#include "../Vector.h"
#include "AinurLexical.h"
#include "AinurState.h"
#include 
#include 
#include 

namespace PsimagLite
{

class Ainur
{

	struct Action {

		Action(String name, AinurState& state)
		    : name_(name)
		    , state_(state)
		{
		}

		template 
		void operator()(A& attr, ContextType& context, bool& hit) const;

	private:

		String name_;
		AinurState& state_;
	};

	struct Action3 {

		Action3(String name, AinurState& state)
		    : name_(name)
		    , state_(state)
		{
		}

		template 
		void operator()(A& attr, ContextType& context, bool& hit) const;

	private:

		String name_;
		AinurState& state_;
	};

	struct myprint {
		template 
		void operator()(const T& t) const
		{
			std::cout << " --------> " << t << '\n';
		}
	};

public:

	typedef std::string::iterator IteratorType;
	typedef Vector::Type VectorCharType;
	typedef AinurState::VectorStringType VectorStringType;

	Ainur(String str);

	String& prefix() { return dummy_; }

	const String& prefix() const { return dummy_; }

	void printUnused(std::ostream& os) const { state_.printUnused(os); }

	void printAll(std::ostream& os) const { state_.printAll(os); }

	template 
	void readValue(SomeType& t, String label) const
	{
		state_.readValue(t, dummy_ + label);
	}

	template 
	void setMap(SomeMapType& map) const
	{
		state_.setMap(map);
	}

	std::string resolve(const std::string& str) const
	{
		return state_.resolve(str);
	}

private:

	void initMacros() { state_.initMacros(); }

	static bool allEmpty(IteratorType first, IteratorType last)
	{
		for (IteratorType it = first; it != last; ++it) {
			if (AinurLexical::isEmptyChar(*it))
				continue;
			return false;
		}

		return true;
	}

	String dummy_;
	AinurState state_;
}; // class AinurSpirit

} // namespace PsimagLite
#endif // _AINUR_SPIRIT_H_
PsimagLite-3.06/src/Ainur/AinurSpirit1.cpp000066400000000000000000000067331446452427400204300ustar00rootroot00000000000000#include "AinurLexical.h"
#include "AinurSpirit.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 

namespace PsimagLite
{

template 
void Ainur::Action::operator()(A& attr, ContextType&, bool&) const
{
	if (name_ == "statement1") {
		String v1 = boost::fusion::at_c<0>(attr);
		String v2 = boost::fusion::at_c<1>(attr);
		state_.assign(v1, v2);
	} else if (name_ == "statement2") {
		String v1 = boost::fusion::at_c<0>(attr);
		String v2 = boost::fusion::at_c<1>(attr);
		state_.declare(v1, v2);
	} else {
		err("Ainur: bad action name " + name_ + "\n");
	}
}

template 
void Ainur::Action3::operator()(A& attr, ContextType&, bool&) const
{
	String v1 = boost::fusion::at_c<0>(attr);
	String v2 = boost::fusion::at_c<1>(attr);
	String v3 = boost::fusion::at_c<2>(attr);
	state_.declare(v1, v2, v3);
}

Ainur::Ainur(String str)
    : dummy_("")
{
	AinurLexical discard(str);
	bool verbose = AinurState::verbose();

	if (verbose)
		std::cerr << str << "\n\n";
#define AINUR_COMMENTS \
	('#' >> *(qi::char_ - qi::eol) >> qi::eol) | qi::eol | qi::space
	namespace qi = boost::spirit::qi;
	namespace ascii = boost::spirit::ascii;
	typedef boost::fusion::vector AttribType;
	typedef boost::fusion::vector
	    Attrib3Type;

	typedef BOOST_TYPEOF(AINUR_COMMENTS) SkipperType;

	qi::rule aToZ;
	qi::rule zeroToNine;
	qi::rule keywords;
	qi::rule value;
	qi::rule typeQualifier;
	qi::rule statement1;
	qi::rule statement2;
	qi::rule statement3;
	qi::rule statement;
	value %= qi::lexeme[+(qi::char_ - qi::char_(";"))];
	aToZ = ascii::char_("a", "z") | ascii::char_("A", "Z");
	zeroToNine = ascii::char_("0", "9");

	typeQualifier %= +(aToZ | ascii::char_(".") | ascii::char_("!"));
	keywords = *(ascii::char_("_")) >> +aToZ >> *(ascii::char_("a", "z") | ascii::char_("A", "Z") | ascii::char_("0", "9") | ascii::char_(":") | ascii::char_("_"));
	statement1 %= keywords >> '=' >> value;
	statement2 %= typeQualifier >> keywords;
	statement3 %= typeQualifier >> keywords >> '=' >> value;

	Action action1("statement1", state_);
	Action action2("statement2", state_);
	Action3 action3("statement3", state_);
	statement %= statement3[action3] | statement2[action2] | statement1[action1];

	IteratorType first = str.begin();
	IteratorType last = str.end();
	qi::phrase_parse(first, last, statement % ";", AINUR_COMMENTS);

	++first;
	if (first != last && !allEmpty(first, last)) {

		qi::parse(first, last, +('#' >> *(qi::char_ - qi::eol) >> qi::eol | qi::eol | qi::space));

		if (first + 1 != last && !allEmpty(first, last)) {
			IteratorType e = (first + 20 < last) ? first + 20 : last;
			err(AinurState::errLabel(AinurState::ERR_PARSE_FAILED,
			    String(first, e)));
		}
	}

	// Deal with macros
	initMacros();
}

String AinurState::ZERO_CHAR_STRING_(1, ' ');

} // namespace PsimagLite
PsimagLite-3.06/src/Ainur/AinurState.h000066400000000000000000000173311446452427400176160ustar00rootroot00000000000000#ifndef AINURSTATE_H
#define AINURSTATE_H
#include "../Matrix.h"
#include "../PsimagLite.h"
#include "../Vector.h"
#include "AinurConvert.hh"
#include "AinurDoubleOrFloat.h"
#include "AinurMacros.hh"
#include 
#include 

namespace PsimagLite
{

class AinurState
{

public:

	typedef Vector::Type VectorSizeType;
	typedef Vector::Type VectorStringType;
	typedef std::complex ComplexType;

	struct myprint {
		template 
		void operator()(const T& t) const
		{
			std::cout << " --------> " << t << '\n';
		}
	};

	enum ErrorEnum {
		ERR_PARSE_UNDECLARED,
		ERR_PARSE_DECLARED,
		ERR_PARSE_FAILED,
		ERR_READ_UNDECLARED,
		ERR_READ_NO_VALUE
	};

	AinurState()
	{
		assert(ZERO_CHAR_STRING_.length() == 1);
		//		if (ZERO_CHAR_STRING_[0] != ' ')
		//			err("Ainur::AinurState should be a
		// singleton\n");

		ZERO_CHAR_STRING_[0] = 0;
	}

	void assign(String k, String v)
	{
		int x = storageIndexByName(k);
		if (x < 0)
			err(errLabel(ERR_PARSE_UNDECLARED, k));

		assert(static_cast(x) < ainurVariables_.size());

		// if (values_[x] != "")
		//	std::cerr<<"Overwriting label "<= 0)
			err(errLabel(ERR_PARSE_DECLARED, key));

		SizeType u = 1;
		SizeType last = d.length();
		assert(last > 0);
		if (last > 1 && d[last - 1] == '!') {
			u = 0;
			d = d.substr(0, last - 1);
		}

		AinurVariable ainurVar({ key, v, d, "NORMAL" });
		ainurVariables_.emplace_back(ainurVar);

		used_.push_back(u);
	}

	void declare(String d, String k) { declare(d, k, ZERO_CHAR_STRING_); }

	void initMacros()
	{
		// install native macros first
		installNativeMacros();

		// then expand
		expandMacrosRecursively();
	}

	void printUnused(std::ostream& os) const
	{
		SizeType n = used_.size();
		bool flag = false;
		for (SizeType i = 0; i < n; ++i) {
			if (used_[i] > 0)
				continue;
			flag = true;
			break;
		}

		if (!flag)
			return;

		os << "Unused keys:\n";

		if (n != ainurVariables_.size())
			err("printUnused: internal error\n");

		for (SizeType i = 0; i < n; ++i) {
			if (used_[i] > 0)
				continue;
			os << ainurVariables_[i].key << "\n";
		}
	}

	void printAll(std::ostream& os) const
	{
		SizeType n = ainurVariables_.size();
		for (SizeType i = 0; i < n; ++i) {
			const AinurVariable& ainurVar = ainurVariables_[i];
			os << ainurVar.type << " " << ainurVar.key << " "
			   << ainurVar.value << "\n";
		}
	}

	template 
	void readValue(SomeType& t, String label) const
	{
		int x = storageIndexByName(label);
		if (x < 0)
			err(errLabel(ERR_READ_UNDECLARED, label));

		assert(static_cast(x) < ainurVariables_.size());

		if (isEmptyValue(ainurVariables_[x].value))
			err(errLabel(ERR_READ_NO_VALUE, label));

		AinurConvert ainurConvert(ainurMacros_);

		ainurConvert.convert(t, ainurVariables_[x]);

		assert(static_cast(x) < used_.size());
		used_[x]++;
	}

	template 
	void setMap(SomeMapType& map) const
	{
		const SizeType n = ainurVariables_.size();
		for (SizeType i = 0; i < n; ++i) {
			if (!used_[i])
				continue;

			const AinurVariable& ainurVar = ainurVariables_[i];
			map[ainurVar.key] = ainurVar.value;
		}
	}

	static bool verbose() { return false; }

	static String errLabel(ErrorEnum e, String key)
	{
		switch (e) {
		case ERR_PARSE_UNDECLARED:
			return "FATAL parse error: Undeclared " + key + "\n" + "You provided a label in the " + "input file that was not recognized.\n" + "Please check the spelling. If you intended " + "to introduce a temporary label,\nyou must "
																									  "declare "
			    + "it first; please see Ainur input format "
			      "documentation.\n";
		case ERR_PARSE_DECLARED:
			return "FATAL parse error: Already declared " + key + "\n" + "You tried to re-declare a variable that was "
										     "already declared.\n"
			    + "If you intended to just provide a value for " + key + " then please remove the declaration word.\n";
		case ERR_PARSE_FAILED:
			return "FATAL parse error: Parsing failed near " + key + "\n" + "This is probably a syntax error.\n";
		case ERR_READ_UNDECLARED:
			return "FATAL read error: No such label " + key + "\n" + "The label " + key + " must appear in the input file\n";
		case ERR_READ_NO_VALUE:
			return "FATAL read error: No value provided for "
			       "label "
			    + key + "\n" + "The label " + key + " must appear in the input file with " + "a non-empty value\n";
		default:
			return "FATAL Ainur error: Unknown error\n";
		}
	}

	std::string resolve(const std::string& str) const
	{
		return ainurMacros_.valueFromFunction(str);
	}

private:

	int storageIndexByName(String key) const
	{
		auto it = std::find_if(ainurVariables_.begin(), ainurVariables_.end(), [&key](const AinurVariable& ainurVar) {
			return (ainurVar.key == key);
		});

		if (it == ainurVariables_.end())
			return -1;
		return it - ainurVariables_.begin();
	}

	static bool isEmptyValue(String s)
	{
		return (s.length() == 0 || s == ZERO_CHAR_STRING_);
	}

	void installNativeMacros()
	{
		for (SizeType i = 0; i < ainurMacros_.total(); ++i) {
			const AinurMacros::NativeMacro& nativeMacro = ainurMacros_.nativeMacro(i);
			declare(nativeMacro.type, nativeMacro.name, nativeMacro.value);
		}
	}

	void expandMacrosRecursively()
	{
		static const SizeType avoidInfMax = 100;
		SizeType avoidInfCounter = 0;
		while (expandMacros()) {
			if (avoidInfCounter++ > avoidInfMax) {
				err("Recursion limit of " + ttos(avoidInfMax) + " exceeded.\n");
			}
		}
	}

	bool expandMacros()
	{
		const SizeType n = ainurVariables_.size();
		bool atLeastOneValueHasMacro = false;
		for (SizeType i = 0; i < n; ++i) {
			if (!used_[i])
				continue;
			std::pair macro = expandOneValue(ainurVariables_[i].value);

			if (!macro.first)
				continue;

			if (macro.second.size() > 0 && macro.second[0] == '!') {
				macro.second = ainurMacros_.procNativeMacro(macro.second);
			}

			ainurVariables_[i].value = macro.second;
			ainurVariables_[i].opaque = "MACRO";
			atLeastOneValueHasMacro = true;
		}

		return atLeastOneValueHasMacro;
	}

	// \[a-zA-Z]+
	std::pair
	expandOneValue(const String& value) const
	{
		const SizeType n = value.length();
		PsimagLite::String macroName;
		PsimagLite::String retString;
		bool hasAtLeastOneMacro = false;
		SizeType status = 0; // 0 = outsite a macro, 1 = inside a macro
		for (SizeType i = 0; i < n; ++i) {
			const char c = value[i];
			if (c == '\\') {
				status = 1;
				continue;
			}

			if (status == 0) {
				retString += c;
				continue;
			}

			if (isValidCharForMacroName(c)) {
				macroName += c;
			} else {

				int x = storageIndexByName(macroName);
				if (x < 0)
					err("No macro named " + macroName + "\n");

				assert(static_cast(x) < ainurVariables_.size());
				retString += unquote(ainurVariables_[x].value) + c;

				macroName = "";
				hasAtLeastOneMacro = true;
				status = 0;
			}
		}

		return std::pair(hasAtLeastOneMacro,
		    unquote(retString));
	}

	static bool isValidCharForMacroName(char c)
	{
		const bool b1 = (c > 96 && c < 123);
		const bool b2 = (c > 64 && c < 91);
		const bool b3 = (c > 47 && c < 58);

		return (b1 || b2 || b3 || c == '_');
	}

	static PsimagLite::String unquote(PsimagLite::String str)
	{
		if (str.length() == 0)
			return str;
		if (str[0] == '"')
			str = str.substr(1, str.length() - 1);
		if (str.length() == 0)
			return str;
		if (str[str.length() - 1] == '"')
			str = str.substr(0, str.length() - 1);
		return str;
	}

	static String ZERO_CHAR_STRING_;
	AinurMacros ainurMacros_;
	std::vector ainurVariables_;
	mutable VectorSizeType used_;
};

} // namespace PsimagLite
#endif // AINURSTATE_H
PsimagLite-3.06/src/Ainur/AinurStatements.h000066400000000000000000000155751446452427400206750ustar00rootroot00000000000000#ifndef AINURSTATEMENT_H
#define AINURSTATEMENT_H
#include "AinurReadable.h"
#include "AinurStore.h"

namespace PsimagLite
{

class AinurStatements
{

public:

	typedef AinurReadable::RealType RealType;
	typedef AinurReadable::VectorStoreType VectorStoreType;
	typedef AinurReadable::StoreType StoreType;
	typedef StoreType::AinurLexicalType AinurLexicalType;
	typedef AinurLexicalType::VectorStringType VectorStringType;

	AinurStatements(const VectorStringType& vecStr, const String& vecChar, const String& escapedChars, const VectorStringType& vecBrace)
	    : vecStr_(vecStr)
	    , vecChar_(vecChar)
	    , escapedChars_(escapedChars)
	    , vecBrace_(vecBrace)
	    , readable_(names_, storage_)
	{
	}

	VectorStringType push(const String& s2, String prefix)
	{
		VectorStringType emptyStringVector;
		String s = s2;
		AinurLexicalType::removeTrailingBlanks(s);
		AinurLexicalType::removeTrailingBlanks(prefix);
		if (s == "")
			return emptyStringVector;
		SizeType storageIndex = 0;

		VectorStringType leftAndRight;
		split(leftAndRight, s, "=");
		AinurLexicalType::removeTrailingWhitespace(leftAndRight);
		if (leftAndRight.size() != 1 && leftAndRight.size() != 2)
			err("Syntax error: " + s + "\n");

		String identifier = procLeftEquality(storageIndex, leftAndRight[0], prefix, s);
		if (leftAndRight.size() == 1)
			return emptyStringVector;

		if (storageIndex >= storage_.size())
			err("StorageIndex too big\n");

		unescape(leftAndRight[1]);
		unescape(identifier);
		StoreType& store = storage_[storageIndex];
		if (store.type() == StoreType::SCALAR && store.subType() == StoreType::GROUP) {
			String right = leftAndRight[1];
			SizeType last = right.length();
			--last;
			bool inBraces = (last < right.length() && right[0] == '{' && right[last] == '}');

			if (!inBraces)
				err("Group must be in braces, " + leftAndRight[0] + "\n");

			leftAndRight[1] = (last < 2) ? "" : right.substr(1, last - 1);
			leftAndRight[0] = identifier + ":";
			return leftAndRight;
		}

		store.setRhs(leftAndRight[1], identifier);

		for (SizeType j = 0; j < store.valueSize(); ++j)
			solveExpression(storageIndex, j);

		return emptyStringVector;
	}

	AinurReadable& readable() { return readable_; }

	const AinurReadable& readable() const { return readable_; }

private:

	String procLeftEquality(SizeType& y, String s, String prefix, String context)
	{
		VectorStringType dotified;
		VectorStringType lhs;
		split(lhs, s, " ");
		SizeType l = lhs.size();
		// require vector.vector.integer FiniteLoops
		// matrix.integer FiniteLoops
		// identifier
		if (l < 1 || l > 3)
			err("Too much or too little on left? -- " + context + " --\n");
		int x = -1;

		if (l == 1) { // identifier
			split(dotified, prefix + lhs[0], ".");
			if (dotified.size() != 1)
				err("Dotified failed " + context + "\n");
			x = readable_.storageIndexByName(dotified[0]);
		} else if (l == 2) { // matrix.integer FiniteLoops
			split(dotified, prefix + lhs[1], ".");
			if (dotified.size() != 1)
				err("Dotified failed " + context + "\n");
			x = assignStorageByName(dotified[0]);
			storage_.push_back(StoreType(lhs[0], ""));
		} else if (l == 3) {
			// require vector.vector.integer FiniteLoops
			split(dotified, prefix + lhs[2], ".");
			if (dotified.size() != 1)
				err("Dotified failed " + context + "\n");
			x = assignStorageByName(dotified[0]);
			storage_.push_back(StoreType(lhs[1], lhs[0]));
		}

		if (x < 0)
			err("Undeclared variable " + dotified[0] + "\n");

		y = x;

		return dotified[0];
	}

	StoreType::Attribute getAttribute(String s, String context) const
	{
		if (s == "require")
			return StoreType::REQUIRED;
		if (s == "const")
			return StoreType::CONST;

		err("Expected let require or const " + context + "\n");
		return StoreType::NONE;
	}

	int assignStorageByName(String name)
	{
		int x = readable_.storageIndexByName(name);
		if (x >= 0)
			err("Already in scope " + name + "\n");
		names_.push_back(name);
		return names_.size() - 1;
	}

	void unescape(String& s) const
	{
		SizeType l = s.length();
		String newStr("");
		for (SizeType i = 0; i < l; ++i) {
			if (s[i] == '@') {
				newStr += getReplacement(i, s, l);
				continue;
			}

			newStr += s[i];
		}

		s = newStr;
	}

	// i @, i+1 s, i+2 0, i+3 @
	String getReplacement(SizeType& i, String s, SizeType l) const
	{
		assert(i < l);
		String oneChar(" ");
		oneChar[0] = s[i];
		if (i + 3 >= l)
			return oneChar;
		char c = s[++i];
		String number;
		SizeType j = i + 1;
		for (; j < l; ++j) {
			if (s[j] == '@')
				break;
			if (s[j] < 48 || s[j] > 57)
				err("Error while replacing string\n");
			number += s[j];
		}

		if (s[j] != '@')
			err("Error while replacing string, no final @ found\n");

		i = j + 1;
		SizeType n = atoi(number.c_str());
		return getReplacement(c, n);
	}

	String getReplacement(char c, SizeType n) const
	{
		if (c == 's') {
			if (n >= vecStr_.size())
				err("Error while replacing string, index too "
				    "big\n");
			return vecStr_[n];
		}

		if (c == 'b') {
			if (n >= vecBrace_.size())
				err("Error while replacing string, index too "
				    "big\n");
			return vecBrace_[n];
		}

		if (c == 'q') {
			if (n >= vecChar_.length())
				err("Error while replacing string, index too "
				    "big\n");
			String oneChar(" ");
			oneChar[0] = vecChar_[n];
			return oneChar;
		}

		if (c == 'e') {
			if (n >= escapedChars_.length())
				err("Error while replacing string, index too "
				    "big\n");
			String oneChar(" ");
			oneChar[0] = escapedChars_[n];
			return oneChar;
		}

		err("Expected s or b or q or e after replacement\n");
		return "";
	}

	// FIXME: Must be generalized to general expressions
	// FIXME: Needs to check what's in scope
	void solveExpression(SizeType ind, SizeType jnd)
	{
		SizeType total = names_.size();
		assert(total == storage_.size());
		StoreType::Type whatType = storage_[ind].type();

		for (SizeType i = 0; i < total; ++i) {
			if (storage_[ind].value(jnd, names_[ind]) != names_[i])
				continue;

			StoreType::Type replType = storage_[i].type();
			if (whatType == Store::SCALAR) {
				assert(jnd == 0);
				// replacement must be scalar
				if (replType != Store::SCALAR)
					err("Must be scalar " + names_[i] + " in " + names_[ind]);

				if (storage_[i].subType() != storage_[ind].subType())
					err("Subtype mismatch " + names_[i] + " in " + names_[ind]);

				storage_[ind].value(jnd, names_[ind]) = storage_[i].value(jnd, names_[i]);
				break;
			}

			if (whatType != Store::VECTOR)
				err("Cannot replace in matrix yet\n");

			assert(whatType == Store::VECTOR);
			if (replType == Store::SCALAR) {
				storage_[ind].value(jnd, names_[ind]) = storage_[i].value(0, names_[i]);
				break;
			}

			err("Replacement in vector can only be scalar\n");
		}
	}

	const VectorStringType& vecStr_;
	const String& vecChar_;
	const String& escapedChars_;
	const VectorStringType& vecBrace_;
	VectorStringType names_;
	VectorStoreType storage_;
	AinurReadable readable_;
}; // class AinurStatements
} // namespace PsimagLite
#endif // AINURSTATEMENT_H
PsimagLite-3.06/src/Ainur/AinurStore.h000066400000000000000000000110631446452427400176260ustar00rootroot00000000000000#ifndef AINURSTORE_H
#define AINURSTORE_H
#include "AinurLexical.h"
#include "Vector.h"

namespace PsimagLite
{

class Store
{

public:

	typedef AinurLexical AinurLexicalType;
	typedef AinurLexicalType::VectorStringType VectorStringType;

	enum Type { UNKNOWN,
		SCALAR,
		VECTOR,
		MATRIX }; // HASH, FUNCTION

	enum SubType { UNDEFINED,
		INTEGER,
		REAL,
		COMPLEX,
		STRING,
		CHAR,
		GROUP };

	enum Attribute { NONE,
		REQUIRED,
		CONST };

	Store(String s, String a)
	    : type_(UNKNOWN)
	    , subType_(UNDEFINED)
	    , attr_(NONE)
	    , used_(0)
	{
		setTypeOf(s);
		if (a != "")
			setAttr(a);
	}

	void setRhs(String rhs, String name)
	{
		value_.clear();
		switch (type_) {
		case SCALAR:
			value_.push_back(rhs);
			break;
		case VECTOR:
			setVectorValue(value_, rhs, name);
			break;
		case MATRIX:
			setMatrixValue(rhs, name);
			break;
		default:
			std::cerr << "setRhs not implemented, rhs= " << rhs
				  << "\n";
			break;
		}
	}

	Type type() const { return type_; }

	SubType subType() const { return subType_; }

	SizeType valueSize() const { return value_.size(); }

	const String& value(SizeType ind, String name) const
	{
		if (ind >= value_.size())
			throw RuntimeError("No value for " + name + "\n");

		return value_[ind];
	}

	String& value(SizeType ind, String name)
	{
		if (ind >= value_.size())
			throw RuntimeError("No value for " + name + "\n");

		return value_[ind];
	}

	void increaseUsage() const { ++used_; }

	SizeType used() const { return used_; }

private:

	void setTypeOf(String s)
	{
		subType_ = subTypeFromString(s);
		if (subType_ != UNDEFINED) {
			type_ = SCALAR;
			return;
		}

		VectorStringType words;
		split(words, s, ".");
		if (words.size() == 0)
			return;

		if (words[0] == "vector") {
			type_ = VECTOR;
			if (words.size() > 1)
				subType_ = subTypeFromString(words[1]);
			return;
		}

		if (words[0] == "matrix") {
			type_ = MATRIX;
			if (words.size() > 1)
				subType_ = subTypeFromString(words[1]);
			return;
		}
	}

	static SubType subTypeFromString(String s)
	{
		if (s == "integer")
			return INTEGER;
		if (s == "real")
			return REAL;
		if (s == "complex")
			return COMPLEX;
		if (s == "char")
			return CHAR;
		if (s == "string")
			return STRING;
		if (s == "group")
			return GROUP;
		return UNDEFINED;
	}

	void setAttr(String s)
	{
		if (s == "require") {
			attr_ = REQUIRED;
			return;
		}

		if (s == "const") {
			attr_ = CONST;
			return;
		}

		err("Unknown attribute " + s + "\n");
	}

	void setVectorValue(VectorStringType& v, String rhs, String name)
	{
		SizeType last = rhs.length();
		if (last < 2)
			err("Vector must be enclosed in brakets, name= " + name + "\n");

		--last;
		if (rhs[0] != '[' || rhs[last] != ']')
			err("Vector must be enclosed in brakets, name= " + name + "\n");

		rhs = (last < 2) ? "" : rhs.substr(1, last - 1);
		AinurLexicalType::removeTrailingBlanks(rhs);
		last = rhs.length();
		if (last > 1 && rhs[0] == '[' && rhs[--last] == ']') {
			// it's really a matrix
			setMatrixValue("[" + rhs + "]", name);
			type_ = MATRIX;
			return;
		}

		split(v, rhs, ",");
	}

	// [[a, b, c], [a, b, c]]
	void setMatrixValue(String rhs, String name)
	{
		SizeType last = rhs.length();
		if (last < 4)
			err("Matrix must be enclosed in brakets\n");

		--last;
		if (rhs[0] != '[' || rhs[last] != ']')
			err("Matrix must be enclosed in brakets " + rhs + "\n");
		assert(last > 2);
		rhs = rhs.substr(1, last - 1);
		AinurLexicalType::removeTrailingBlanks(rhs);
		VectorStringType tmp;
		split(tmp, rhs, "[");
		// a, b, c],
		// a, b, c]
		SizeType rows = tmp.size();
		assert(rows > 0);
		SizeType cols = 0;
		value_.clear();
		SizeType offset = 2;
		for (SizeType row = 0; row < rows; ++row) {
			VectorStringType v;
			String s = tmp[row];
			AinurLexicalType::removeTrailingBlanks(s);
			SizeType last = s.length();
			if (last > 0 && s[--last] == ',')
				s = s.substr(0, last);

			s = "[" + s;
			setVectorValue(v, s, name);
			SizeType thisCol = v.size();
			if (row == 0) {
				cols = thisCol;
				value_.resize(rows * cols + 2);
				value_[0] = ttos(rows);
				value_[1] = ttos(cols);
			} else if (cols != thisCol) {
				err("Malformed matrix, " + name + "\n");
			}

			appendToVecStr(value_, v, offset);
			offset += v.size();
		}
	}

	void appendToVecStr(VectorStringType& dest, const VectorStringType& src, SizeType offset) const
	{
		SizeType n = src.size();
		assert(offset + n <= dest.size());
		for (SizeType i = 0; i < n; ++i)
			dest[offset + i] = src[i];
	}

	Type type_;
	SubType subType_;
	Attribute attr_;
	VectorStringType value_;
	mutable SizeType used_;
};
} // namespace PsimagLite
#endif // AINURSTORE_H
PsimagLite-3.06/src/Ainur/Config.make.sample000066400000000000000000000031311446452427400207030ustar00rootroot00000000000000# PsimagLite support is needed by PsimagLite drivers
LDFLAGS = -L../../../PsimagLite/lib -lpsimaglite

# Compiler to use. If using MPI then say mpicxx here (or mpic++)
# and also say -DUSE_MPI below
CXX = g++

# We're using ansi C++
CXX += -pedantic -std=c++11

# Enable MPI (you must set the proper
# compiler wrapper under CXX above)
# CPPFLAGS += -DUSE_MPI

# Here add your lapack and blas libraries or say NO_LAPACK
# CPPFLAGS += -DNO_LAPACK
# If on MacOs please say LDFLAGS += -framework Accelerate
LDFLAGS += -llapack -lblas

# Here add -lpthread if threading is needed and also
# set -DUSE_PTHREADS below
LDFLAGS += -lpthread

# Enable pthreads
CPPFLAGS += -DUSE_PTHREADS

# Enable warnings and treat warnings as errors
CPPFLAGS += -Wall -Werror -DUSE_BOOST

CPPFLAGS += -I/usr/include/hdf5/serial


# This disables debugging
CPPFLAGS += -DNDEBUG

# Optimization level here
CPPFLAGS += -O3

# This enables partial debugging (make sure to comment out previous line)
#CPPFLAGS +=   -g3

# This enables additional debugging
#CPPFLAGS += -D_GLIBCXX_DEBUG -D_GLIBCXX_PROFILE

# This makes the code use long instead of short integers
#CPPFLAGS +=-DUSE_LONG

# This makes the code use float instead of double
#CPPFLAGS += -DUSE_FLOAT

# This enables signals
#CPPFLAGS +=-DUSE_SIGNALS

# This enables gsl support
#CPPFLAGS +=-DUSE_GSL
#LDFLAGS += -lgsl -lgslcblas

# This enables the custom allocator (use only for debugging)
#CPPFLAGS += -DUSE_CUSTOM_ALLOCATOR

#Change basis even for un-needed operators
#CPPFLAGS += -DOPERATORS_CHANGE_ALL

# Specify the strip command to use (or use true to disable)
STRIP_COMMAND = strip

PsimagLite-3.06/src/Ainur/configure.pl000077500000000000000000000035361446452427400177110ustar00rootroot00000000000000#!/usr/bin/perl
=pod
Copyright (c) 2009-2017, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************

=cut
use warnings;
use strict;

use lib "../../../PsimagLite/scripts";
use Make;

my @drivers = ();

createMakefile();

sub createMakefile
{
	Make::backupMakefile();
	if (!(-r "Config.make")) {
		my $cmd = "cp Config.make.sample Config.make";
		system($cmd);
		print STDERR "$0: Executed $cmd\n";
	}

	my $fh;
	open($fh, ">", "Makefile") or die "Cannot open Makefile for writing: $!\n";

	local *FH = $fh;
	my @units = qw(test testReal);
	my $combinedUnits = combine("",\@units,".o ");
	my $combinedUnits2 = combine("./",\@units,".cpp ");

	print FH< Makefile.dep

clean: Makefile.dep
\trm -f core* *.o *.dep *.a @units

include Makefile.dep

EOF

	close($fh);
	print STDERR "File Makefile has been written\n";
}

sub combine
{
	my ($pre,$a,$post) = @_;
	my $n = scalar(@$a);
	my $buffer = "";
	for (my $i = 0; $i < $n; ++$i) {
		$buffer .= $pre.$a->[$i].$post;
	}

	return $buffer;
}

PsimagLite-3.06/src/Ainur/function.txt000066400000000000000000000000361446452427400177460ustar00rootroot000000000000000 0
0.3 0.09
1 1
2 4
3 9
4 16
PsimagLite-3.06/src/Ainur/input0.ain000066400000000000000000000011621446452427400172710ustar00rootroot00000000000000##Ainur1.0
TotalNumberOfSites=16;
NumberOfTerms=1;
DegreesOfFreedom=1;
GeometryKind=chain;
GeometryOptions="ConstantValues";

dir0:Connectors=[1.0];

hubbardU=[1.0, ...];
potentialV=[0.0, ...];

Model="HubbardOneBand";
SolverOptions="none";
Version="53725d9b8f22615ccccc782082f4cd6f51a4e374";
OutputFile="data0.txt";
InfiniteLoopKeptStates=100;
FiniteLoops=[
	[7, 100, 0],
	[-7, 100, 0],
        [-7, 100, 0],
	[7, 100, 0]];
TargetElectronsUp=8;
TargetElectronsDown=8;

#string AinurFromFile = blahblah;
function myfunction = \AinurFromFile("function.txt");

real useit = \myfunction(%t);

vector myvector = [\useit, \useit];
PsimagLite-3.06/src/Ainur/input1.ain000066400000000000000000000002771446452427400173000ustar00rootroot00000000000000##Ainur1.0
int TotalNumberOfSites=16;

vector myv=[0.5 i 0.0, 0.0 i 0.3];
vector myv2;
myv2=[4.2,...x10];

string Model="HubbardOneBand";
Model="2";

matrix mymatrix=[
[5, 4, 6],
[7, 8, 9]];
PsimagLite-3.06/src/Ainur/prelude.ain000066400000000000000000000013121446452427400175070ustar00rootroot00000000000000integer TotalNumberOfSites;
integer NumberOfTerms;
integer DegreesOfFreedom;
string GeometryKind;
string GeometryOptions;
vector dir0:Connectors;
vector dir1:Connectors;
integer LadderLeg;
vector hubbardU;
vector potentialV;
string Model;
string SolverOptions;
string Version;
integer InfiniteLoopKeptStates;
string OutputFile;
matrix.integer FiniteLoops ;
integer RepeatFiniteLoopsFrom;
integer RepeatFiniteLoopsTimes;
integer TargetElectronsUp;
integer TargetElectronsDown;
real GsWeight;
real TSPTau;
integer TSPTimeSteps;
integer TSPAdvanceEach;
string TSPAlgorithm;
vector.integer TSPSites;
vector.integer TSPLoops;
string TSPProductOrSum;
string TSPOperator;
string OperatorExpression;
integer Threads = 1;

PsimagLite-3.06/src/Ainur/test.cpp000066400000000000000000000025241446452427400170470ustar00rootroot00000000000000#include "Ainur.h"
#include 
#include 

void partiallyReadSomething(const PsimagLite::Ainur& ainur)
{
	SizeType n = 0;
	ainur.readValue(n, "TotalNumberOfSites");
	std::cout << "Read: TotalNumberOfSites=" << n << "\n";

	PsimagLite::String m;
	ainur.readValue(m, "Model");
	std::cout << m << "\n";

	std::string v2;
	ainur.readValue(v2, "useit");
	std::cout << v2;
	std::cout << std::endl;

	std::vector v3;
	ainur.readValue(v3, "myvector");
	double t = 0.3;
	std::vector v3double(v3.size());
	for (SizeType i = 0; i < v3.size(); ++i) {
		PsimagLite::String str = v3[i];
		PsimagLite::replaceAll(str, "%t", std::to_string(t));
		str = ainur.resolve(str);
		v3double[i] = PsimagLite::atof(str);
	}

	std::cout << v3double.size() << "\n";
	if (v3double.size() == 2) {
		std::cout << v3double[0] << " " << v3double[1] << "\n";
	}
}

int main(int argc, char** argv)
{
	if (argc == 1)
		return 1;

	PsimagLite::String str;
	for (int i = 1; i < argc; ++i) {
		std::ifstream fin(argv[i]);
		PsimagLite::String str2;

		fin.seekg(0, std::ios::end);
		str2.reserve(fin.tellg());
		fin.seekg(0, std::ios::beg);

		str2.assign((std::istreambuf_iterator(fin)),
		    std::istreambuf_iterator());
		fin.close();

		str += str2;
	}

	PsimagLite::Ainur ainur(str);
	// ainur.printAll(std::cout);
	partiallyReadSomething(ainur);
}
PsimagLite-3.06/src/Ainur/testReal.cpp000066400000000000000000000017311446452427400176520ustar00rootroot00000000000000#include "Ainur.h"
#include "Matrix.h"
#include 

void partiallyReadSomething(const PsimagLite::Ainur& ainur)
{
	SizeType n = 0;
	ainur.readValue(n, "TotalNumberOfSites");
	std::cout << "Read: TotalNumberOfSites=" << n << "\n";

	PsimagLite::String m;
	ainur.readValue(m, "Model");
	std::cout << m << "\n";

	std::vector v2; //(10);
	ainur.readValue(v2, "myv2");
	std::cout << v2;

	PsimagLite::Matrix mat;
	ainur.readValue(mat, "mymatrix");
	std::cout << mat;
}

int main(int argc, char** argv)
{
	if (argc == 1)
		return 1;

	PsimagLite::String str;
	for (int i = 1; i < argc; ++i) {
		std::ifstream fin(argv[i]);
		PsimagLite::String str2;

		fin.seekg(0, std::ios::end);
		str2.reserve(fin.tellg());
		fin.seekg(0, std::ios::beg);

		str2.assign((std::istreambuf_iterator(fin)),
		    std::istreambuf_iterator());
		fin.close();

		str += str2;
	}

	PsimagLite::Ainur ainur(str);
	// ainur.printAll(std::cout);
	partiallyReadSomething(ainur);
}
PsimagLite-3.06/src/AkimaSpline.h000066400000000000000000000056121446452427400166550ustar00rootroot00000000000000#ifndef AKIMA_H_
#define AKIMA_H_

#include 
#include 
#include 

//! A class to interpolate using akima spline
template 
class AkimaSpline
{

	typedef typename VectorType::value_type RealType;

	struct AkimaStruct {
		RealType x0, x1, a0, a1, a2, a3;
	};

public:

	typedef std::pair IntervalType;

	AkimaSpline(const VectorType& x, const VectorType& s)
	{
		if (x.size() != s.size())
			throw RuntimeError(
			    "Number of X and Y points must be the same\n");
		if (x.size() < 3)
			throw RuntimeError("Number of X too small\n");
		VectorType sprime;
		calculateSprime(sprime, x, s);
		for (SizeType i = 0; i < x.size() - 1; i++) {
			AkimaStruct ak;
			ak.x0 = x[i];
			ak.x1 = x[i + 1];
			ak.a0 = s[i];
			ak.a1 = sprime[i];
			RealType u = x[i + 1] - x[i];
			RealType ds = (s[i + 1] - s[i]);
			ak.a2 = (3 * ds - (2 * sprime[i] + sprime[i + 1]) * u) / (u * u);
			ak.a3 = ((sprime[i] + sprime[i + 1]) * u - 2 * ds) / (u * u * u);
			akimaStruct_.push_back(ak);
		}
		SizeType k = akimaStruct_.size() - 1;
		interval_ = IntervalType(akimaStruct_[0].x0, akimaStruct_[k].x1);
	}

	RealType operator()(const RealType& x) const
	{
		SizeType i = findRange(x);
		return functionFor(x, i);
	}

	IntervalType getInterval() const { return interval_; }

private:

	RealType functionFor(const RealType& x, SizeType i) const
	{
		const AkimaStruct& ak = akimaStruct_[i];
		RealType u = x - ak.x0;
		return ak.a0 + ak.a1 * u + ak.a2 * u * u + ak.a3 * u * u * u;
	}

	// FIXME: make this function faster
	SizeType findRange(const RealType& x) const
	{
		if (x < interval_.first || x > interval_.second)
			throw RuntimeError("Akima: out of range\n");
		for (SizeType i = 0; i < akimaStruct_.size(); i++)
			if (x >= akimaStruct_[i].x0 && x <= akimaStruct_[i].x1)
				return i;

		throw RuntimeError("Akima: findRange(): internal error\n");
	}

	void calculateSprime(VectorType& sprime, const VectorType& x, const VectorType& s) const
	{
		VectorType d, w;
		calculateD(d, x, s);
		calculateW(w, d);
		sprime.resize(x.size());
		for (SizeType i = 0; i < sprime.size(); i++) {
			RealType denom = w[i] + w[i + 2];
			if (denom == 0) {
				sprime[i] = (d[i + 1] + d[i + 2]) * 0.5;
				continue;
			}
			sprime[i] = w[i + 2] * d[i + 1] + w[i] * d[i + 2];
			sprime[i] /= denom;
		}
	}

	void calculateD(VectorType& d, const VectorType& x, const VectorType& s) const
	{
		SizeType k = x.size();
		d.resize(k + 3);
		for (SizeType i = 2; i <= k; i++)
			d[i] = (s[i - 1] - s[i - 2]) / (x[i - 1] - x[i - 2]);
		d[1] = 2 * d[2] - d[3];
		d[0] = 2 * d[1] - d[2];
		d[k + 1] = 2 * d[k] - d[k - 1];
		d[k + 2] = 2 * d[k + 1] - d[k];
	}

	void calculateW(VectorType& w, const VectorType& d) const
	{
		w.resize(d.size() - 1);
		for (SizeType i = 0; i < w.size(); i++)
			w[i] = fabs(d[i + 1] - d[i]);
	}

	typename Vector::Type akimaStruct_;
	IntervalType interval_;
};

#endif // AKIMA_H_
PsimagLite-3.06/src/AllocatorCpu.h000066400000000000000000000076771446452427400170650ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*!
 *
 *
 */
#ifndef ALLOCATOR_CPU_H
#define ALLOCATOR_CPU_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#ifdef USE_CUSTOM_ALLOCATOR
#include "MemoryCpu.h"
#endif

#ifndef USE_SHORT
typedef long unsigned int SizeType;
#else
typedef uint32_t SizeType;
#endif

namespace PsimagLite
{

template ::value>
struct IsEnumClass : std::false_type {
};

template 
struct IsEnumClass
    : std::integral_constant<
	  bool,
	  !std::is_convertible<
	      T,
	      typename std::underlying_type::type>::value> {
};

inline div_t div(int a, int b) { return std::div(a, b); }

#ifdef USE_CUSTOM_ALLOCATOR
template 
class AllocatorCpu : public std::allocator
{
	typedef typename std::allocator BaseType;

	typedef MemoryCpu MemoryCpuType;
	typedef unsigned char ByteType;

public:

	template 
	struct rebind {
		typedef AllocatorCpu other;
	}; // struct rebind

	AllocatorCpu() { }

	// FIXME: needs template constraints here
	template 
	AllocatorCpu(const OtherType& x)
	    : std::allocator(x)
	{
	}

	typename BaseType::pointer allocate(typename BaseType::size_type n,
	    void* = 0)
	{
		if (n > this->max_size())
			throw std::runtime_error("Bad allocation\n");

		typename BaseType::pointer x = (typename BaseType::pointer)globalMemoryCpu.allocate(
		    n * sizeof(T));

		return static_cast(x);
	}

	void deallocate(typename BaseType::pointer p,
	    typename BaseType::size_type n)
	{
		globalMemoryCpu.deallocate(p);
	}

}; // class AllocatorCpu
#endif

template 
class Allocator
{
public:

#ifdef USE_CUSTOM_ALLOCATOR
	typedef AllocatorCpu Type;
#else
	typedef std::allocator Type;
#endif
}; // class Allocator

template 
class EnableIf
{
};

template 
class EnableIf
{
public:

	typedef T Type;
};

template 
struct RemoveConst {
	typedef T Type;
};

template 
struct RemoveConst {
	typedef T Type;
};

template 
struct IsStringLike {
	enum { True = false };
};

template 
struct IsStringLike, A>> {
	enum { True = true };
};

typedef std::basic_string, Allocator::Type>
    String;
typedef std::basic_istringstream, Allocator::Type>
    IstringStream;

class OstringStream
{
public:

	typedef std::basic_ostringstream, Allocator::Type>
	    OstringStreamType;

	OstringStream(int prec) { data_.precision(prec); }

	int precision(int prec) { return data_.precision(prec); }

	OstringStreamType& operator()() { return data_; }

private:

	OstringStreamType data_;
};

class RuntimeError : public std::runtime_error
{
public:

	explicit RuntimeError(const String& what_arg)
	    : std::runtime_error(what_arg.c_str())
	{
	}
};

class RangeError : public std::range_error
{
public:

	explicit RangeError(const String& what_arg)
	    : std::range_error(what_arg.c_str())
	{
	}
};

class LogicError : public std::logic_error
{
public:

	explicit LogicError(const String& what_arg)
	    : std::logic_error(what_arg.c_str())
	{
	}
};

} // namespace PsimagLite

/*@}*/
#endif // ALLOCATOR_CPU_H
PsimagLite-3.06/src/AlmostEqual.h000066400000000000000000000070511446452427400167060ustar00rootroot00000000000000// BEGIN LICENSE BLOCK
/*
Copyright (c) 2009 , UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************


*/
// END LICENSE BLOCK
/** \ingroup PsimagLite */
/*@{*/

/*! \file AlmostEqual.h
 *
 * Almost equal
 */

#ifndef ALMOST_EQUAL_H
#define ALMOST_EQUAL_H
#include "Matrix.h"

namespace PsimagLite
{
template 
class AlmostEqual
{
public:

	AlmostEqual(const RealType& eps)
	    : eps_(eps)
	{
	}

	//		template
	//		bool operator()(
	//			const Matrix& a,
	//			const Matrix& b)
	//		{
	//			for (SizeType i=0;ieps_) {
	//						std::cerr<<"a("<
#include 
#include 
#include 
#include 
#include 

namespace PsimagLite
{

class ApplicationInfo
{

public:

	typedef String RunIdType;

	ApplicationInfo(const PsimagLite::String& name)
	    : name_(name)
	    , pid_(getpid())
	    , runId_(runIdInternal())
	    , isFinalized_(false)
	{
	}

	void finalize() { isFinalized_ = true; }

	time_t unixTime(bool arg = false) const
	{
		struct timeval tv;
		gettimeofday(&tv, 0);
		return (arg) ? tv.tv_usec : tv.tv_sec;
	}

	String getTimeDate() const
	{
		time_t tt = unixTime();
		return asctime(localtime(&tt));
	}

	String hostname() const
	{
		int len = 1024;
		char* name = new char[len];
		int ret = gethostname(name, len);
		String retString;
		if (ret != 0) {
			retString = "UNKNOWN";
		} else {
			retString = name;
		}

		delete[] name;

		return retString;
	}

	const RunIdType runId() const { return runId_; }

	unsigned int pid() const { return pid_; }

	void write(String label, IoSerializer& serializer) const
	{
		String root = label;
		if (!isFinalized_) {
			serializer.createGroup(root);

			serializer.write(root + "/Name", name_);
			serializer.write(root + "/RunId", runId_);
			serializer.write(root + "/UnixTimeStart",
			    unixTime(false));
		} else {
			serializer.write(root + "/UnixTimeEnd",
			    unixTime(false));
		}
	}

	static void setEnv(String name, String value)
	{
		int ret = setenv(name.c_str(), value.c_str(), true);
		if (ret != 0)
			throw RuntimeError("Could not setenv " + name + "=" + value + "\n");
		std::cout << "Set " << name << "=" << value << "\n";
	}

	friend std::ostream& operator<<(std::ostream& os,
	    const ApplicationInfo& ai)
	{
		if (ai.isFinalized_)
			printFinalLegacy(os, ai);
		else
			printInit(os, ai);

		return os;
	}

private:

	static void printInit(std::ostream& os, const ApplicationInfo& ai)
	{
		os << ai.getTimeDate();
		os << "Hostname: " << ai.hostname() << "\n";
		os << "RunID=" << ai.runId_ << "\n";
		os << "UnixTimeStart=" << ai.unixTime(false) << "\n";
		os << "SizeType=" << sizeof(SizeType) << "\n";
	}

	static void printFinalLegacy(std::ostream& os,
	    const ApplicationInfo& ai)
	{
		OstringStream msg(std::cout.precision());
		msg() << ai.name_ << "\nsizeof(SizeType)=" << sizeof(SizeType)
		      << "\n";
#ifdef USE_FLOAT
		msg() << ai.name_ << " using float\n";
#else
		msg() << ai.name_ << " using double\n";
#endif
		msg() << "UnixTimeEnd=" << ai.unixTime(false) << "\n";
		msg() << ai.getTimeDate();
		os << msg().str();
	}

	RunIdType runIdInternal() const
	{
		unsigned int p = getpid();
		time_t tt = unixTime(true);
		MersenneTwister mt(tt + p);
		unsigned int x = tt ^ mt.random();
		OstringStream msgg(std::cout.precision());
		OstringStream::OstringStreamType& msg = msgg();
		msg << x;
		x = p ^ mt.random();
		msg << x;
		unsigned long int y = atol(msg.str().c_str());
		y ^= mt.random();
		x = BitManip::countKernighan(y);
		OstringStream msgg2(std::cout.precision());
		OstringStream::OstringStreamType& msg2 = msgg2();
		msg2 << y;
		if (x < 10)
			msg2 << "0";
		msg2 << x;
		return msg2.str();
	}

	long unsigned int convertToLuint(PsimagLite::String str) const
	{
		long unsigned int sum = 0;
		long unsigned int prod = 1;
		int l = str.length();
		assert(l < 20);

		for (int i = 0; i < l; ++i) {
			unsigned int c = str[l - i - 1] - 48;
			sum += prod * c;
			prod *= 10;
		}

		return sum;
	}

	PsimagLite::String name_;
	unsigned int pid_;
	const RunIdType runId_;
	bool isFinalized_;
}; // class ApplicationInfo

std::ostream& operator<<(std::ostream& os, const ApplicationInfo& ai);

} // namespace PsimagLite

/*@}*/
#endif // APPLICATION_INFO_H
PsimagLite-3.06/src/BLAS.h000066400000000000000000001746231446452427400152120ustar00rootroot00000000000000//-*-C++-*-
// ****************************************************************************
// * C++ wrapper for BLAS                                                     *
// *                                                                          *
// * Thomas Schulthess, ORNL, October 1999                                    *
// * Richard Thigpen, ORNL, June 2003                                         *
// ****************************************************************************

#ifndef PSIMAG_BLAS
#define PSIMAG_BLAS
#include "AllocatorCpu.h"
#include 

/** \file BLAS.h
 *  \author Thomas C. Schulthess and Richard N. Thigpen
 */

/** \brief Namespace encapsulating all PsiMag tools.
 */
namespace psimag
{

/** \brief Namespace for psimag wrappers of BLAS functions
 */
namespace BLAS
{

#ifndef PSI_BLAS_64
	typedef int IntegerForBlasType;
#else
	typedef long int IntegerForBlasType;
#endif

	//===============================================================
	// MISSING STUFF (BY G.A.)
	// ==============================================================
	extern "C" double ddot_(IntegerForBlasType*, double*, IntegerForBlasType*, double*, IntegerForBlasType*);

	// ============================================================================
	// = Level 3 BLAS             GEMM
	// ============================================================================
	extern "C" void sgemm_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, IntegerForBlasType*, const float*, const float*, IntegerForBlasType*, const float*, IntegerForBlasType*, const float*, float*, IntegerForBlasType*);

	extern "C" void dgemm_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, IntegerForBlasType*, const double*, const double*, IntegerForBlasType*, const double*, IntegerForBlasType*, const double*, double*, IntegerForBlasType*);

	extern "C" void cgemm_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);

	extern "C" void zgemm_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);

	//*****************************************************************************
	//*                           SYMM
	//*****************************************************************************

	extern "C" void ssymm_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, const float*, const float*, IntegerForBlasType*, const float*, IntegerForBlasType*, const float*, const float*, IntegerForBlasType*);

	extern "C" void dsymm_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, const double*, const double*, IntegerForBlasType*, const double*, IntegerForBlasType*, const double*, const double*, IntegerForBlasType*);

	extern "C" void csymm_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*);
	extern "C" void zsymm_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*);

	//*****************************************************************************
	//*                           HEMM
	//*****************************************************************************

	extern "C" void chemm_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);

	extern "C" void zhemm_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);

	// ****************************************************************************
	// *                          SYRK
	// ****************************************************************************

	extern "C" void ssyrk_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, const float*, const float*, IntegerForBlasType*, const float*, float*, IntegerForBlasType*);

	extern "C" void dsyrk_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, const double*, const double*, IntegerForBlasType*, const double*, double*, IntegerForBlasType*);

	extern "C" void csyrk_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);

	extern "C" void zsyrk_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);

	// ****************************************************************************
	// *                          HERK
	// ****************************************************************************
	extern "C" void cherk_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);

	extern "C" void zherk_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);
	// ****************************************************************************
	// *                          SYR2K
	// ****************************************************************************
	extern "C" void ssyr2k_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, const float*, const float*, IntegerForBlasType*, const float*, IntegerForBlasType*, const float*, float*, IntegerForBlasType*);

	extern "C" void dsyr2k_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, const double*, const double*, IntegerForBlasType*, const double*, IntegerForBlasType*, const double*, double*, IntegerForBlasType*);

	extern "C" void csyr2k_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);

	extern "C" void zsyr2k_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);
	// ****************************************************************************
	// *                          HER2k
	// ****************************************************************************
	extern "C" void cher2k_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);

	extern "C" void zher2k_(char*, char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);
	// ****************************************************************************
	// *                          TRMM
	// ****************************************************************************
	extern "C" void strmm_(char*, char*, char*, char*, IntegerForBlasType*, IntegerForBlasType*, const float*, const float*, IntegerForBlasType*, float*, IntegerForBlasType*);

	extern "C" void dtrmm_(char*, char*, char*, char*, IntegerForBlasType*, IntegerForBlasType*, const double*, const double*, IntegerForBlasType*, double*, IntegerForBlasType*);

	extern "C" void ctrmm_(char*, char*, char*, char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);

	extern "C" void ztrmm_(char*, char*, char*, char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);
	// ****************************************************************************
	// *                          TRSM
	// ****************************************************************************
	extern "C" void strsm_(char*, char*, char*, char*, IntegerForBlasType*, IntegerForBlasType*, const float*, const float*, IntegerForBlasType*, float*, IntegerForBlasType*);

	extern "C" void dtrsm_(char*, char*, char*, char*, IntegerForBlasType*, IntegerForBlasType*, const double*, const double*, IntegerForBlasType*, double*, IntegerForBlasType*);

	extern "C" void ctrsm_(char*, char*, char*, char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);

	extern "C" void ztrsm_(char*, char*, char*, char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);
	// ****************************************************************************
	// *    Level 2 BLAS          GEMV
	// ****************************************************************************
	extern "C" void sgemv_(char*, IntegerForBlasType*, IntegerForBlasType*, const float*, const float*, IntegerForBlasType*, const float*, IntegerForBlasType*, const float*, float*, IntegerForBlasType*);

	extern "C" void dgemv_(char*, IntegerForBlasType*, IntegerForBlasType*, const double*, const double*, IntegerForBlasType*, const double*, IntegerForBlasType*, const double*, double*, IntegerForBlasType*);

	extern "C" void cgemv_(char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);

	extern "C" void zgemv_(char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);
	// ****************************************************************************
	// *                          GBMV
	// ****************************************************************************
	extern "C" void sgbmv_(char*, IntegerForBlasType*, IntegerForBlasType*, IntegerForBlasType*, IntegerForBlasType*, const float*, const float*, IntegerForBlasType*, const float*, IntegerForBlasType*, const float*, float*, IntegerForBlasType*);

	extern "C" void dgbmv_(char*, IntegerForBlasType*, IntegerForBlasType*, IntegerForBlasType*, IntegerForBlasType*, const double*, const double*, IntegerForBlasType*, const double*, IntegerForBlasType*, const double*, double*, IntegerForBlasType*);

	extern "C" void cgbmv_(char*, IntegerForBlasType*, IntegerForBlasType*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);

	extern "C" void zgbmv_(char*, IntegerForBlasType*, IntegerForBlasType*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);

	// ****************************************************************************
	// *                          HEMV
	// ****************************************************************************
	extern "C" void chemv_(char*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);

	extern "C" void zhemv_(char*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);
	// ****************************************************************************
	// *                         HBMV
	// ****************************************************************************
	extern "C" void chbmv_(char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);

	extern "C" void zhbmv_(char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);
	// ****************************************************************************
	// *                         HPMV
	// ****************************************************************************
	extern "C" void chpmv_(char*, IntegerForBlasType*, const std::complex*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);

	extern "C" void zhpmv_(char*, IntegerForBlasType*, const std::complex*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);
	// ******************************************************************************
	// *                         SYMV
	// ******************************************************************************
	extern "C" void ssymv_(char*, IntegerForBlasType*, const float*, const float*, IntegerForBlasType*, const float*, IntegerForBlasType*, const float*, float*, IntegerForBlasType*);

	extern "C" void dsymv_(char*, IntegerForBlasType*, const double*, const double*, IntegerForBlasType*, const double*, IntegerForBlasType*, const double*, double*, IntegerForBlasType*);
	// ******************************************************************************
	// *                         SBMV
	// ******************************************************************************
	extern "C" void ssbmv_(char*, IntegerForBlasType*, IntegerForBlasType*, const float*, const float*, IntegerForBlasType*, const float*, IntegerForBlasType*, const float*, float*, IntegerForBlasType*);

	extern "C" void dsbmv_(char*, IntegerForBlasType*, IntegerForBlasType*, const double*, const double*, IntegerForBlasType*, const double*, IntegerForBlasType*, const double*, double*, IntegerForBlasType*);
	// ******************************************************************************
	// *                         SPMV
	// ******************************************************************************
	extern "C" void sspmv_(char*, IntegerForBlasType*, const float*, const float*, const float*, IntegerForBlasType*, const float*, float*, IntegerForBlasType*);

	extern "C" void dspmv_(char*, IntegerForBlasType*, const double*, const double*, const double*, IntegerForBlasType*, const double*, double*, IntegerForBlasType*);
	// ******************************************************************************
	// *                         TRMV
	// ******************************************************************************
	extern "C" void strmv_(char*, char*, char*, IntegerForBlasType*, const float*, IntegerForBlasType*, float*, IntegerForBlasType*);

	extern "C" void dtrmv_(char*, char*, char*, IntegerForBlasType*, const double*, IntegerForBlasType*, double*, IntegerForBlasType*);

	extern "C" void ctrmv_(char*, char*, char*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);

	extern "C" void ztrmv_(char*, char*, char*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);

	// ******************************************************************************
	// *                         TBMV
	// ******************************************************************************
	extern "C" void stbmv_(char*, char*, char*, IntegerForBlasType*, IntegerForBlasType*, const float*, IntegerForBlasType*, float*, IntegerForBlasType*);

	extern "C" void dtbmv_(char*, char*, char*, IntegerForBlasType*, IntegerForBlasType*, const double*, IntegerForBlasType*, double*, IntegerForBlasType*);

	extern "C" void ctbmv_(char*, char*, char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);

	extern "C" void ztbmv_(char*, char*, char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);
	// ******************************************************************************
	// *                         TPMV
	// ******************************************************************************
	extern "C" void stpmv_(char*, char*, char*, IntegerForBlasType*, const float*, float*, IntegerForBlasType*);

	extern "C" void dtpmv_(char*, char*, char*, IntegerForBlasType*, const double*, double*, IntegerForBlasType*);

	extern "C" void ctpmv_(char*, char*, char*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);

	extern "C" void ztpmv_(char*, char*, char*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);
	// ******************************************************************************
	// *                         TRSV
	// ******************************************************************************
	extern "C" void strsv_(char*, char*, char*, IntegerForBlasType*, const float*, IntegerForBlasType*, float*, IntegerForBlasType*);

	extern "C" void dtrsv_(char*, char*, char*, IntegerForBlasType*, const double*, IntegerForBlasType*, double*, IntegerForBlasType*);

	extern "C" void ctrsv_(char*, char*, char*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);

	extern "C" void ztrsv_(char*, char*, char*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);
	// ******************************************************************************
	// *                         TBSV
	// ******************************************************************************
	extern "C" void stbsv_(char*, char*, char*, IntegerForBlasType*, IntegerForBlasType*, const float*, IntegerForBlasType*, float*, IntegerForBlasType*);

	extern "C" void dtbsv_(char*, char*, char*, IntegerForBlasType*, IntegerForBlasType*, const double*, IntegerForBlasType*, double*, IntegerForBlasType*);

	extern "C" void ctbsv_(char*, char*, char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);

	extern "C" void ztbsv_(char*, char*, char*, IntegerForBlasType*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);
	// ******************************************************************************
	// *                         TPSV
	// ******************************************************************************
	extern "C" void stpsv_(char*, char*, char*, IntegerForBlasType*, const float*, float*, IntegerForBlasType*);

	extern "C" void dtpsv_(char*, char*, char*, IntegerForBlasType*, const double*, double*, IntegerForBlasType*);

	extern "C" void ctpsv_(char*, char*, char*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);

	extern "C" void ztpsv_(char*, char*, char*, IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);
	// ******************************************************************************
	// *                         GER
	// ******************************************************************************
	extern "C" void sger_(IntegerForBlasType*, IntegerForBlasType*, const float*, const float*, IntegerForBlasType*, const float*, IntegerForBlasType*, float*, IntegerForBlasType*);

	extern "C" void dger_(IntegerForBlasType*, IntegerForBlasType*, const double*, const double*, IntegerForBlasType*, const double*, IntegerForBlasType*, double*, IntegerForBlasType*);
	// ******************************************************************************
	// *                         GERU
	// ******************************************************************************
	extern "C" void cgeru_(IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);

	extern "C" void zgeru_(IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);
	// ******************************************************************************
	// *                         GERC
	// ******************************************************************************
	extern "C" void cgerc_(IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);

	extern "C" void zgerc_(IntegerForBlasType*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);
	// ******************************************************************************
	// *                         HER
	// ******************************************************************************
	extern "C" void cher_(char*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);

	extern "C" void zher_(char*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);
	// ******************************************************************************
	// *                         HPR
	// ******************************************************************************
	extern "C" void chpr_(char*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, std::complex*);

	extern "C" void zhpr_(char*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, std::complex*);
	// ******************************************************************************
	// *                         HER2
	// ******************************************************************************
	extern "C" void cher2_(char*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);

	extern "C" void zher2_(char*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);
	// ******************************************************************************
	// *                         HPR2
	// ******************************************************************************
	extern "C" void chpr2_(char*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, std::complex*);

	extern "C" void zhpr2_(char*, IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, const std::complex*, IntegerForBlasType*, std::complex*);
	// ******************************************************************************
	// *                         SYR
	// ******************************************************************************
	extern "C" void ssyr_(char*, IntegerForBlasType*, const float*, const float*, IntegerForBlasType*, float*, IntegerForBlasType*);

	extern "C" void dsyr_(char*, IntegerForBlasType*, const double*, const double*, IntegerForBlasType*, double*, IntegerForBlasType*);
	// ******************************************************************************
	// *                         SPR
	// ******************************************************************************
	extern "C" void sspr_(char*, IntegerForBlasType*, const float*, const float*, IntegerForBlasType*, float*);

	extern "C" void dspr_(char*, IntegerForBlasType*, const double*, const double*, IntegerForBlasType*, double*);
	// ******************************************************************************
	// *                         SYR2
	// ******************************************************************************
	extern "C" void ssyr2_(char*, IntegerForBlasType*, const float*, const float*, IntegerForBlasType*, const float*, IntegerForBlasType*, float*, IntegerForBlasType*);

	extern "C" void dsyr2_(char*, IntegerForBlasType*, const double*, const double*, IntegerForBlasType*, const double*, IntegerForBlasType*, double*, IntegerForBlasType*);
	// ******************************************************************************
	// *                         SPR2
	// ******************************************************************************
	extern "C" void sspr2_(char*, IntegerForBlasType*, const float*, const float*, IntegerForBlasType*, const float*, IntegerForBlasType*, float*);

	extern "C" void dspr2_(char*, IntegerForBlasType*, const double*, const double*, IntegerForBlasType*, const double*, IntegerForBlasType*, double*);
	// ******************************************************************************
	// *Level 1 BLAS
	// ******************************************************************************

	extern "C" void srotg_(float*, float*, float*, float*);
	extern "C" void drotg_(double*, double*, double*, double*);

	extern "C" void srotmg_(float*, float*, float*, float*, float*);
	extern "C" void drotmg_(double*, double*, double*, double*, double*);

	extern "C" void srot_(IntegerForBlasType*, float*, IntegerForBlasType*, float*, IntegerForBlasType*, const float*, const float*);
	extern "C" void drot_(IntegerForBlasType*, double*, IntegerForBlasType*, double*, IntegerForBlasType*, const double*, const double*);

	extern "C" void srotm_(IntegerForBlasType*, float*, IntegerForBlasType*, float*, IntegerForBlasType*, const float*);
	extern "C" void drotm_(IntegerForBlasType*, double*, IntegerForBlasType*, double*, IntegerForBlasType*, const double*);

	extern "C" void sswap_(IntegerForBlasType*, float*, IntegerForBlasType*, float*, IntegerForBlasType*);

	extern "C" void dswap_(IntegerForBlasType*, double*, IntegerForBlasType*, double*, IntegerForBlasType*);

	extern "C" void cswap_(IntegerForBlasType*, std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);

	extern "C" void zswap_(IntegerForBlasType*, std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);

	extern "C" void saxpy_(IntegerForBlasType*, const float*, const float*, IntegerForBlasType*, float*, IntegerForBlasType*);

	extern "C" void daxpy_(IntegerForBlasType*, const double*, const double*, IntegerForBlasType*, double*, IntegerForBlasType*);

	extern "C" void caxpy_(IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);

	extern "C" void zaxpy_(IntegerForBlasType*, const std::complex*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);

	extern "C" void scopy_(IntegerForBlasType*, const float*, IntegerForBlasType*, float*, IntegerForBlasType*);

	extern "C" void dcopy_(IntegerForBlasType*, const double*, IntegerForBlasType*, double*, IntegerForBlasType*);

	extern "C" void ccopy_(IntegerForBlasType*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);

	extern "C" void zcopy_(IntegerForBlasType*, const std::complex*, IntegerForBlasType*, std::complex*, IntegerForBlasType*);

	extern "C" void sscal_(IntegerForBlasType*, const float*, float*, IntegerForBlasType*);

	extern "C" void dscal_(IntegerForBlasType*, const double*, double*, IntegerForBlasType*);

	extern "C" void cscal_(IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);

	extern "C" void zscal_(IntegerForBlasType*, const std::complex*, std::complex*, IntegerForBlasType*);

	// ============================================================================
	inline double DOT(IntegerForBlasType n, double* dx, IntegerForBlasType incx, double* dy, IntegerForBlasType incy)
	{
		return ddot_(&n, dx, &incx, dy, &incy);
	}

	// ============================================================================
	inline void GEMM(char c1, char c2, IntegerForBlasType sX, IntegerForBlasType sY, IntegerForBlasType sZ, const float& a, const float* x, IntegerForBlasType sx, const float* y, IntegerForBlasType sy, const float& b, float* z, IntegerForBlasType sz)
	{
		sgemm_(&c1, &c2, &sX, &sY, &sZ, &a, x, &sx, y, &sy, &b, z, &sz);
	}

	inline void GEMM(char c1, char c2, IntegerForBlasType sX, IntegerForBlasType sY, IntegerForBlasType sZ, const double& a, const double* x, IntegerForBlasType sx, const double* y, IntegerForBlasType sy, const double& b, double* z, IntegerForBlasType sz)
	{
		dgemm_(&c1, &c2, &sX, &sY, &sZ, &a, x, &sx, y, &sy, &b, z, &sz);
	}

	inline void GEMM(char c1, char c2, IntegerForBlasType sX, IntegerForBlasType sY, IntegerForBlasType sZ, const std::complex& a, const std::complex* x, IntegerForBlasType sx, const std::complex* y, IntegerForBlasType sy, const std::complex& b, std::complex* z, IntegerForBlasType sz)
	{
		cgemm_(&c1, &c2, &sX, &sY, &sZ, &a, x, &sx, y, &sy, &b, z, &sz);
	}

	inline void GEMM(char c1, char c2, IntegerForBlasType sX, IntegerForBlasType sY, IntegerForBlasType sZ, const std::complex& a, const std::complex* x, IntegerForBlasType sx, const std::complex* y, IntegerForBlasType sy, const std::complex& b, std::complex* z, IntegerForBlasType sz)
	{
		/* When  TRANSA = 'N' or 'n' then
			LDA must be at least  max( 1, m ), otherwise  LDA must be at
		least  max( 1, k ).*/

		if (c1 == 'N' || c1 == 'n') {
			if (sx < std::max(1, sX)) {
				throw PsimagLite::RuntimeError(
				    "GEMM lda < max(1, m)\n");
			}
		} else {
			if (sx < std::max(1, sZ)) {
				throw PsimagLite::RuntimeError(
				    "GEMM lda < max(1, k)\n");
			}
		}

		zgemm_(&c1, &c2, &sX, &sY, &sZ, &a, x, &sx, y, &sy, &b, z, &sz);
	}

	// ***************************************************************************
	inline void SYMM(char c1, char c2, IntegerForBlasType sX, IntegerForBlasType sY, const float& a, const float* x, IntegerForBlasType sx, const float* y, IntegerForBlasType sy, const float& b, float* z, IntegerForBlasType sz)
	{
		ssymm_(&c1, &c2, &sX, &sY, &a, x, &sx, y, &sy, &b, z, &sz);
	}

	inline void SYMM(char c1, char c2, IntegerForBlasType sX, IntegerForBlasType sY, const double& a, const double* x, IntegerForBlasType sx, const double* y, IntegerForBlasType sy, const double& b, double* z, IntegerForBlasType sz)
	{
		dsymm_(&c1, &c2, &sX, &sY, &a, x, &sx, y, &sy, &b, z, &sz);
	}
	inline void SYMM(char c1, char c2, IntegerForBlasType sX, IntegerForBlasType sY, const std::complex& a, const std::complex* x, IntegerForBlasType sx, const std::complex* y, IntegerForBlasType sy, const std::complex& b, std::complex* z, IntegerForBlasType sz)
	{
		csymm_(&c1, &c2, &sX, &sY, &a, x, &sx, y, &sy, &b, z, &sz);
	}
	inline void SYMM(char c1, char c2, IntegerForBlasType sX, IntegerForBlasType sY, const std::complex& a, const std::complex* x, IntegerForBlasType sx, const std::complex* y, IntegerForBlasType sy, const std::complex& b, std::complex* z, IntegerForBlasType sz)
	{
		zsymm_(&c1, &c2, &sX, &sY, &a, x, &sx, y, &sy, &b, z, &sz);
	}
	// ---------------------------------------------------------------------------
	inline void HEMM(char c1, char c2, IntegerForBlasType sX, IntegerForBlasType sY, const std::complex& a, const std::complex* x, IntegerForBlasType sx, const std::complex* y, IntegerForBlasType, const std::complex& b, std::complex* z, IntegerForBlasType sz)
	{
		chemm_(&c1, &c2, &sX, &sY, &a, x, &sx, y, &sx, &b, z, &sz);
	}
	inline void HEMM(char c1, char c2, IntegerForBlasType sX, IntegerForBlasType sY, const std::complex& a, const std::complex* x, IntegerForBlasType sx, const std::complex* y, IntegerForBlasType, const std::complex& b, std::complex* z, IntegerForBlasType sz)
	{
		zhemm_(&c1, &c2, &sX, &sY, &a, x, &sx, y, &sx, &b, z, &sz);
	}
	// **************************************************************************
	inline void SYRK(char UPLO, char TRANS, IntegerForBlasType N, IntegerForBlasType K, const float& ALPHA, const float* A, IntegerForBlasType LDA, const float& BETA, float* C, IntegerForBlasType LDC)
	{
		ssyrk_(&UPLO, &TRANS, &N, &K, &ALPHA, A, &LDA, &BETA, C, &LDC);
	}
	inline void SYRK(char UPLO, char TRANS, IntegerForBlasType N, IntegerForBlasType K, const double& ALPHA, const double* A, IntegerForBlasType LDA, const double& BETA, double* C, IntegerForBlasType LDC)
	{
		dsyrk_(&UPLO, &TRANS, &N, &K, &ALPHA, A, &LDA, &BETA, C, &LDC);
	}
	inline void SYRK(char UPLO, char TRANS, IntegerForBlasType N, IntegerForBlasType K, const std::complex& ALPHA, const std::complex* A, IntegerForBlasType LDA, const std::complex& BETA, std::complex* C, IntegerForBlasType LDC)
	{
		csyrk_(&UPLO, &TRANS, &N, &K, &ALPHA, A, &LDA, &BETA, C, &LDC);
	}
	inline void SYRK(char UPLO, char TRANS, IntegerForBlasType N, IntegerForBlasType K, const std::complex& ALPHA, const std::complex* A, IntegerForBlasType LDA, const std::complex& BETA, std::complex* C, IntegerForBlasType LDC)
	{
		zsyrk_(&UPLO, &TRANS, &N, &K, &ALPHA, A, &LDA, &BETA, C, &LDC);
	}

	// ***************************************************************************
	inline void HERK(char UPLO, char TRANS, IntegerForBlasType N, IntegerForBlasType K, const std::complex& ALPHA, const std::complex* A, IntegerForBlasType LDA, const std::complex& BETA, std::complex* C, IntegerForBlasType LDC)
	{
		cherk_(&UPLO, &TRANS, &N, &K, &ALPHA, A, &LDA, &BETA, C, &LDC);
	}
	inline void HERK(char UPLO, char TRANS, IntegerForBlasType N, IntegerForBlasType K, const std::complex& ALPHA, const std::complex* A, IntegerForBlasType LDA, const std::complex& BETA, std::complex* C, IntegerForBlasType LDC)
	{
		zherk_(&UPLO, &TRANS, &N, &K, &ALPHA, A, &LDA, &BETA, C, &LDC);
	}
	// ***************************************************************************
	inline void SYR2K(char uplo, char trans, IntegerForBlasType n, IntegerForBlasType k, const float& alpha, const float* A, IntegerForBlasType lda, const float* B, IntegerForBlasType ldb, const float& beta, float* C, IntegerForBlasType ldc)
	{
		ssyr2k_(&uplo, &trans, &n, &k, &alpha, A, &lda, B, &ldb, &beta, C, &ldc);
	}
	inline void SYR2K(char uplo, char trans, IntegerForBlasType n, IntegerForBlasType k, const double& alpha, const double* A, IntegerForBlasType lda, const double* B, IntegerForBlasType ldb, const double& beta, double* C, IntegerForBlasType ldc)
	{
		dsyr2k_(&uplo, &trans, &n, &k, &alpha, A, &lda, B, &ldb, &beta, C, &ldc);
	}
	inline void SYR2k(char uplo, char trans, IntegerForBlasType n, IntegerForBlasType k, const std::complex& alpha, const std::complex* A, IntegerForBlasType lda, const std::complex* B, IntegerForBlasType ldb, const std::complex& beta, std::complex* C, IntegerForBlasType ldc)
	{
		csyr2k_(&uplo, &trans, &n, &k, &alpha, A, &lda, B, &ldb, &beta, C, &ldc);
	}
	inline void SYR2k(char uplo, char trans, IntegerForBlasType n, IntegerForBlasType k, const std::complex& alpha, const std::complex* A, IntegerForBlasType lda, const std::complex* B, IntegerForBlasType ldb, const std::complex& beta, std::complex* C, IntegerForBlasType ldc)
	{
		zsyr2k_(&uplo, &trans, &n, &k, &alpha, A, &lda, B, &ldb, &beta, C, &ldc);
	}
	// ***************************************************************************
	inline void HER2k(char uplo, char trans, IntegerForBlasType n, IntegerForBlasType k, const std::complex& alpha, const std::complex* A, IntegerForBlasType lda, const std::complex* B, IntegerForBlasType ldb, const std::complex& beta, std::complex* C, IntegerForBlasType ldc)
	{
		cher2k_(&uplo, &trans, &n, &k, &alpha, A, &lda, B, &ldb, &beta, C, &ldc);
	}
	inline void HER2k(char uplo, char trans, IntegerForBlasType n, IntegerForBlasType k, const std::complex& alpha, const std::complex* A, IntegerForBlasType lda, const std::complex* B, IntegerForBlasType ldb, const std::complex& beta, std::complex* C, IntegerForBlasType ldc)
	{
		zher2k_(&uplo, &trans, &n, &k, &alpha, A, &lda, B, &ldb, &beta, C, &ldc);
	}
	// ********************************************************************************
	inline void TRMM(char side, char uplo, char transa, char diag, IntegerForBlasType m, IntegerForBlasType n, const float& alpha, const float* A, IntegerForBlasType lda, float* B, IntegerForBlasType ldb)
	{
		strmm_(&side, &uplo, &transa, &diag, &m, &n, &alpha, A, &lda, B, &ldb);
	}
	inline void TRMM(char side, char uplo, char transa, char diag, IntegerForBlasType m, IntegerForBlasType n, const double& alpha, const double* A, IntegerForBlasType lda, double* B, IntegerForBlasType ldb)
	{
		dtrmm_(&side, &uplo, &transa, &diag, &m, &n, &alpha, A, &lda, B, &ldb);
	}
	inline void TRMM(char side, char uplo, char transa, char diag, IntegerForBlasType m, IntegerForBlasType n, const std::complex& alpha, const std::complex* A, IntegerForBlasType lda, std::complex* B, IntegerForBlasType ldb)
	{
		ctrmm_(&side, &uplo, &transa, &diag, &m, &n, &alpha, A, &lda, B, &ldb);
	}
	inline void TRMM(char side, char uplo, char transa, char diag, IntegerForBlasType m, IntegerForBlasType n, const std::complex& alpha, const std::complex* A, IntegerForBlasType lda, std::complex* B, IntegerForBlasType ldb)
	{
		ztrmm_(&side, &uplo, &transa, &diag, &m, &n, &alpha, A, &lda, B, &ldb);
	}
	// ********************************************************************************
	inline void TRSM(char side, char uplo, char transa, char diag, IntegerForBlasType m, IntegerForBlasType n, const float& alpha, const float* A, IntegerForBlasType lda, float* B, IntegerForBlasType ldb)
	{
		strsm_(&side, &uplo, &transa, &diag, &m, &n, &alpha, A, &lda, B, &ldb);
	}
	inline void TRSM(char side, char uplo, char transa, char diag, IntegerForBlasType m, IntegerForBlasType n, const double& alpha, const double* A, IntegerForBlasType lda, double* B, IntegerForBlasType ldb)
	{
		dtrsm_(&side, &uplo, &transa, &diag, &m, &n, &alpha, A, &lda, B, &ldb);
	}
	inline void TRSM(char side, char uplo, char transa, char diag, IntegerForBlasType m, IntegerForBlasType n, const std::complex& alpha, const std::complex* A, IntegerForBlasType lda, std::complex* B, IntegerForBlasType ldb)
	{
		ctrsm_(&side, &uplo, &transa, &diag, &m, &n, &alpha, A, &lda, B, &ldb);
	}
	inline void TRSM(char side, char uplo, char transa, char diag, IntegerForBlasType m, IntegerForBlasType n, const std::complex& alpha, const std::complex* A, IntegerForBlasType lda, std::complex* B, IntegerForBlasType ldb)
	{
		ztrsm_(&side, &uplo, &transa, &diag, &m, &n, &alpha, A, &lda, B, &ldb);
	}
	// ***************************************************************************

	inline void GEMV(char c, IntegerForBlasType M, IntegerForBlasType N, const float& alpha, const float* A, IntegerForBlasType ldA, const float* x, IntegerForBlasType incX, const float& beta, float* y, IntegerForBlasType incY)
	{
		sgemv_(&c, &M, &N, &alpha, A, &ldA, x, &incX, &beta, y, &incY);
	}
	// ----------------------------------------------------------------------------
	inline void GEMV(char c, IntegerForBlasType M, IntegerForBlasType N, const double& alpha, const double* A, IntegerForBlasType ldA, const double* x, IntegerForBlasType incX, const double& beta, double* y, IntegerForBlasType incY)
	{
		dgemv_(&c, &M, &N, &alpha, A, &ldA, x, &incX, &beta, y, &incY);
	}
	// ---------------------------------------------------------------------------
	inline void GEMV(char c, IntegerForBlasType M, IntegerForBlasType N, const std::complex& alpha, const std::complex* A, IntegerForBlasType ldA, const std::complex* x, IntegerForBlasType incX, const std::complex& beta, std::complex* y, IntegerForBlasType incY)
	{
		cgemv_(&c, &M, &N, &alpha, A, &ldA, x, &incX, &beta, y, &incY);
	}
	// ---------------------------------------------------------------------------
	inline void GEMV(char c, IntegerForBlasType M, IntegerForBlasType N, const std::complex& alpha, const std::complex* A, IntegerForBlasType ldA, const std::complex* x, IntegerForBlasType incX, const std::complex& beta, std::complex* y, IntegerForBlasType incY)
	{
		zgemv_(&c, &M, &N, &alpha, A, &ldA, x, &incX, &beta, y, &incY);
	}
	// ----------------------------------------------------------------------------
	inline void GBMV(char trans, IntegerForBlasType m, IntegerForBlasType n, IntegerForBlasType kl, IntegerForBlasType ku, const float& alpha, const float* A, IntegerForBlasType lda, const float* x, IntegerForBlasType incx, const float& beta, float* y, IntegerForBlasType incy)
	{
		sgbmv_(&trans, &m, &n, &kl, &ku, &alpha, A, &lda, x, &incx, &beta, y, &incy);
	}
	inline void GBMV(char trans, IntegerForBlasType m, IntegerForBlasType n, IntegerForBlasType kl, IntegerForBlasType ku, const double& alpha, const double* A, IntegerForBlasType lda, const double* x, IntegerForBlasType incx, const double& beta, double* y, IntegerForBlasType incy)
	{
		dgbmv_(&trans, &m, &n, &kl, &ku, &alpha, A, &lda, x, &incx, &beta, y, &incy);
	}
	inline void GBMV(char trans, IntegerForBlasType m, IntegerForBlasType n, IntegerForBlasType kl, IntegerForBlasType ku, const std::complex& alpha, const std::complex* A, IntegerForBlasType lda, const std::complex* x, IntegerForBlasType incx, const std::complex& beta, std::complex* y, IntegerForBlasType incy)
	{
		cgbmv_(&trans, &m, &n, &kl, &ku, &alpha, A, &lda, x, &incx, &beta, y, &incy);
	}
	inline void GBMV(char trans, IntegerForBlasType m, IntegerForBlasType n, IntegerForBlasType kl, IntegerForBlasType ku, const std::complex& alpha, const std::complex* A, IntegerForBlasType lda, const std::complex* x, IntegerForBlasType incx, const std::complex& beta, std::complex* y, IntegerForBlasType incy)
	{
		zgbmv_(&trans, &m, &n, &kl, &ku, &alpha, A, &lda, x, &incx, &beta, y, &incy);
	}
	// ****************************************************************************
	inline void HEMV(char uplo, IntegerForBlasType n, const std::complex& alpha, const std::complex* a, IntegerForBlasType lda, const std::complex* x, IntegerForBlasType incx, const std::complex& beta, std::complex* y, IntegerForBlasType incy)
	{
		chemv_(&uplo, &n, &alpha, a, &lda, x, &incx, &beta, y, &incy);
	}
	inline void HEMV(char uplo, IntegerForBlasType n, const std::complex& alpha, const std::complex* a, IntegerForBlasType lda, const std::complex* x, IntegerForBlasType incx, const std::complex& beta, std::complex* y, IntegerForBlasType incy)
	{
		zhemv_(&uplo, &n, &alpha, a, &lda, x, &incx, &beta, y, &incy);
	}
	// **************************************************************************
	inline void HBMV(char uplo, IntegerForBlasType n, IntegerForBlasType k, const std::complex& alpha, const std::complex* a, IntegerForBlasType lda, const std::complex* x, IntegerForBlasType incx, const std::complex& beta, std::complex* y, IntegerForBlasType incy)
	{
		chbmv_(&uplo, &n, &k, &alpha, a, &lda, x, &incx, &beta, y, &incy);
	}
	inline void HBMV(char uplo, IntegerForBlasType n, IntegerForBlasType k, const std::complex& alpha, const std::complex* a, IntegerForBlasType lda, const std::complex* x, IntegerForBlasType incx, const std::complex& beta, std::complex* y, IntegerForBlasType incy)
	{
		zhbmv_(&uplo, &n, &k, &alpha, a, &lda, x, &incx, &beta, y, &incy);
	}
	// ***************************************************************************
	inline void HPMV(char uplo, IntegerForBlasType n, const std::complex& alpha, const std::complex* ap, const std::complex* x, IntegerForBlasType incx, const std::complex& beta, std::complex* y, IntegerForBlasType incy)
	{
		chpmv_(&uplo, &n, &alpha, ap, x, &incx, &beta, y, &incy);
	}
	inline void HPMV(char uplo, IntegerForBlasType n, const std::complex& alpha, const std::complex* ap, const std::complex* x, IntegerForBlasType incx, const std::complex& beta, std::complex* y, IntegerForBlasType incy)
	{
		zhpmv_(&uplo, &n, &alpha, ap, x, &incx, &beta, y, &incy);
	}
	// ***************************************************************************
	inline void SYMV(char uplo, IntegerForBlasType n, const float& alpha, const float* a, IntegerForBlasType lda, const float* x, IntegerForBlasType incx, const float& beta, float* y, IntegerForBlasType incy)
	{
		ssymv_(&uplo, &n, &alpha, a, &lda, x, &incx, &beta, y, &incy);
	}
	inline void SYMV(char uplo, IntegerForBlasType n, const double& alpha, const double* a, IntegerForBlasType lda, const double* x, IntegerForBlasType incx, const double& beta, double* y, IntegerForBlasType incy)
	{
		dsymv_(&uplo, &n, &alpha, a, &lda, x, &incx, &beta, y, &incy);
	}
	// ****************************************************************************
	inline void SBMV(char uplo, IntegerForBlasType n, IntegerForBlasType k, const float& alpha, const float* a, IntegerForBlasType lda, const float* x, IntegerForBlasType incx, const float& beta, float* y, IntegerForBlasType incy)
	{
		ssbmv_(&uplo, &n, &k, &alpha, a, &lda, x, &incx, &beta, y, &incy);
	}
	inline void SBMV(char uplo, IntegerForBlasType n, IntegerForBlasType k, const double& alpha, const double* a, IntegerForBlasType lda, const double* x, IntegerForBlasType incx, const double& beta, double* y, IntegerForBlasType incy)
	{
		dsbmv_(&uplo, &n, &k, &alpha, a, &lda, x, &incx, &beta, y, &incy);
	}
	// ****************************************************************************
	inline void SPMV(char uplo, IntegerForBlasType n, const float& alpha, const float* ap, const float* x, IntegerForBlasType incx, const float& beta, float* y, IntegerForBlasType incy)
	{
		sspmv_(&uplo, &n, &alpha, ap, x, &incx, &beta, y, &incy);
	}
	inline void SPMV(char uplo, IntegerForBlasType n, const double& alpha, const double* ap, const double* x, IntegerForBlasType incx, const double& beta, double* y, IntegerForBlasType incy)
	{
		dspmv_(&uplo, &n, &alpha, ap, x, &incx, &beta, y, &incy);
	}
	// ****************************************************************************
	inline void TRMV(char uplo, char trans, char diag, IntegerForBlasType n, const float* a, IntegerForBlasType lda, float* x, IntegerForBlasType incx)
	{
		strmv_(&uplo, &trans, &diag, &n, a, &lda, x, &incx);
	}
	inline void TRMV(char uplo, char trans, char diag, IntegerForBlasType n, const double* a, IntegerForBlasType lda, double* x, IntegerForBlasType incx)
	{
		dtrmv_(&uplo, &trans, &diag, &n, a, &lda, x, &incx);
	}
	inline void TRMV(char uplo, char trans, char diag, IntegerForBlasType n, const std::complex* a, IntegerForBlasType lda, std::complex* x, IntegerForBlasType incx)
	{
		ctrmv_(&uplo, &trans, &diag, &n, a, &lda, x, &incx);
	}
	inline void TRMV(char uplo, char trans, char diag, IntegerForBlasType n, const std::complex* a, IntegerForBlasType lda, std::complex* x, IntegerForBlasType incx)
	{
		ztrmv_(&uplo, &trans, &diag, &n, a, &lda, x, &incx);
	}
	// ****************************************************************************
	inline void TBMV(char uplo, char trans, char diag, IntegerForBlasType n, IntegerForBlasType k, const float* a, IntegerForBlasType lda, float* x, IntegerForBlasType incx)
	{
		stbmv_(&uplo, &trans, &diag, &n, &k, a, &lda, x, &incx);
	}
	inline void TBMV(char uplo, char trans, char diag, IntegerForBlasType n, IntegerForBlasType k, const double* a, IntegerForBlasType lda, double* x, IntegerForBlasType incx)
	{
		dtbmv_(&uplo, &trans, &diag, &n, &k, a, &lda, x, &incx);
	}
	inline void TBMV(char uplo, char trans, char diag, IntegerForBlasType n, IntegerForBlasType k, const std::complex* a, IntegerForBlasType lda, std::complex* x, IntegerForBlasType incx)
	{
		ctbmv_(&uplo, &trans, &diag, &n, &k, a, &lda, x, &incx);
	}
	inline void TBMV(char uplo, char trans, char diag, IntegerForBlasType n, IntegerForBlasType k, const std::complex* a, IntegerForBlasType lda, std::complex* x, IntegerForBlasType incx)
	{
		ztbmv_(&uplo, &trans, &diag, &n, &k, a, &lda, x, &incx);
	}
	// ****************************************************************************
	inline void TPMV(char uplo, char trans, char diag, IntegerForBlasType n, const float* ap, float* x, IntegerForBlasType incx)
	{
		stpmv_(&uplo, &trans, &diag, &n, ap, x, &incx);
	}
	inline void TPMV(char uplo, char trans, char diag, IntegerForBlasType n, const double* ap, double* x, IntegerForBlasType incx)
	{
		dtpmv_(&uplo, &trans, &diag, &n, ap, x, &incx);
	}
	inline void TPMV(char uplo, char trans, char diag, IntegerForBlasType n, const std::complex* ap, std::complex* x, IntegerForBlasType incx)
	{
		ctpmv_(&uplo, &trans, &diag, &n, ap, x, &incx);
	}
	inline void TPMV(char uplo, char trans, char diag, IntegerForBlasType n, const std::complex* ap, std::complex* x, IntegerForBlasType incx)
	{
		ztpmv_(&uplo, &trans, &diag, &n, ap, x, &incx);
	}
	// ****************************************************************************
	inline void TRSV(char uplo, char trans, char diag, IntegerForBlasType n, const float* a, IntegerForBlasType lda, float* x, IntegerForBlasType incx)
	{
		strsv_(&uplo, &trans, &diag, &n, a, &lda, x, &incx);
	}
	inline void TRSV(char uplo, char trans, char diag, IntegerForBlasType n, const double* a, IntegerForBlasType lda, double* x, IntegerForBlasType incx)
	{
		dtrsv_(&uplo, &trans, &diag, &n, a, &lda, x, &incx);
	}
	inline void TRSV(char uplo, char trans, char diag, IntegerForBlasType n, const std::complex* a, IntegerForBlasType lda, std::complex* x, IntegerForBlasType incx)
	{
		ctrsv_(&uplo, &trans, &diag, &n, a, &lda, x, &incx);
	}
	inline void TRSV(char uplo, char trans, char diag, IntegerForBlasType n, const std::complex* a, IntegerForBlasType lda, std::complex* x, IntegerForBlasType incx)
	{
		ztrsv_(&uplo, &trans, &diag, &n, a, &lda, x, &incx);
	}
	// ****************************************************************************
	inline void TBSV(char uplo, char trans, char diag, IntegerForBlasType n, IntegerForBlasType k, const float* a, IntegerForBlasType lda, float* x, IntegerForBlasType incx)
	{
		stbsv_(&uplo, &trans, &diag, &n, &k, a, &lda, x, &incx);
	}
	inline void TBSV(char uplo, char trans, char diag, IntegerForBlasType n, IntegerForBlasType k, const double* a, IntegerForBlasType lda, double* x, IntegerForBlasType incx)
	{
		dtbsv_(&uplo, &trans, &diag, &n, &k, a, &lda, x, &incx);
	}
	inline void TBSV(char uplo, char trans, char diag, IntegerForBlasType n, IntegerForBlasType k, const std::complex* a, IntegerForBlasType lda, std::complex* x, IntegerForBlasType incx)
	{
		ctbsv_(&uplo, &trans, &diag, &n, &k, a, &lda, x, &incx);
	}
	inline void TBSV(char uplo, char trans, char diag, IntegerForBlasType n, IntegerForBlasType k, const std::complex* a, IntegerForBlasType lda, std::complex* x, IntegerForBlasType incx)
	{
		ztbsv_(&uplo, &trans, &diag, &n, &k, a, &lda, x, &incx);
	}
	// ****************************************************************************
	inline void TPSV(char uplo, char trans, char diag, IntegerForBlasType n, const float* ap, float* x, IntegerForBlasType incx)
	{
		stpsv_(&uplo, &trans, &diag, &n, ap, x, &incx);
	}
	inline void TPSV(char uplo, char trans, char diag, IntegerForBlasType n, const double* ap, double* x, IntegerForBlasType incx)
	{
		dtpsv_(&uplo, &trans, &diag, &n, ap, x, &incx);
	}
	inline void TPSV(char uplo, char trans, char diag, IntegerForBlasType n, const std::complex* ap, std::complex* x, IntegerForBlasType incx)
	{
		ctpsv_(&uplo, &trans, &diag, &n, ap, x, &incx);
	}
	inline void TPSV(char uplo, char trans, char diag, IntegerForBlasType n, const std::complex* ap, std::complex* x, IntegerForBlasType incx)
	{
		ztpsv_(&uplo, &trans, &diag, &n, ap, x, &incx);
	}
	// ****************************************************************************
	inline void GER(IntegerForBlasType m, IntegerForBlasType n, const float& alpha, const float* x, IntegerForBlasType incx, const float* y, IntegerForBlasType incy, float* a, IntegerForBlasType lda)
	{
		sger_(&m, &n, &alpha, x, &incx, y, &incy, a, &lda);
	}
	inline void GER(IntegerForBlasType m, IntegerForBlasType n, const double& alpha, const double* x, IntegerForBlasType incx, const double* y, IntegerForBlasType incy, double* a, IntegerForBlasType lda)
	{
		dger_(&m, &n, &alpha, x, &incx, y, &incy, a, &lda);
	}
	// ****************************************************************************
	inline void GERU(IntegerForBlasType m, IntegerForBlasType n, const std::complex& alpha, const std::complex* x, IntegerForBlasType incx, const std::complex* y, IntegerForBlasType incy, std::complex* a, IntegerForBlasType lda)
	{
		cgeru_(&m, &n, &alpha, x, &incx, y, &incy, a, &lda);
	}
	inline void GERU(IntegerForBlasType m, IntegerForBlasType n, const std::complex& alpha, const std::complex* x, IntegerForBlasType incx, const std::complex* y, IntegerForBlasType incy, std::complex* a, IntegerForBlasType lda)
	{
		zgeru_(&m, &n, &alpha, x, &incx, y, &incy, a, &lda);
	}
	// ****************************************************************************
	inline void GERC(IntegerForBlasType m, IntegerForBlasType n, const std::complex& alpha, const std::complex* x, IntegerForBlasType incx, const std::complex* y, IntegerForBlasType incy, std::complex* a, IntegerForBlasType lda)
	{
		cgerc_(&m, &n, &alpha, x, &incx, y, &incy, a, &lda);
	}
	inline void GERC(IntegerForBlasType m, IntegerForBlasType n, const std::complex& alpha, const std::complex* x, IntegerForBlasType incx, const std::complex* y, IntegerForBlasType incy, std::complex* a, IntegerForBlasType lda)
	{
		zgerc_(&m, &n, &alpha, x, &incx, y, &incy, a, &lda);
	}
	// *****************************************************************************
	inline void HER(char uplo, IntegerForBlasType n, const std::complex& alpha, const std::complex* x, IntegerForBlasType incx, std::complex* a, IntegerForBlasType lda)
	{
		cher_(&uplo, &n, &alpha, x, &incx, a, &lda);
	}
	inline void HER(char uplo, IntegerForBlasType n, const std::complex& alpha, const std::complex* x, IntegerForBlasType incx, std::complex* a, IntegerForBlasType lda)
	{
		zher_(&uplo, &n, &alpha, x, &incx, a, &lda);
	}
	// *****************************************************************************
	inline void HPR(char uplo, IntegerForBlasType n, const std::complex& alpha, const std::complex* x, IntegerForBlasType incx, std::complex* ap)
	{
		chpr_(&uplo, &n, &alpha, x, &incx, ap);
	}
	inline void HPR(char uplo, IntegerForBlasType n, const std::complex& alpha, const std::complex* x, IntegerForBlasType incx, std::complex* ap)
	{
		zhpr_(&uplo, &n, &alpha, x, &incx, ap);
	}
	// *****************************************************************************
	inline void HER2(char uplo, IntegerForBlasType n, const std::complex& alpha, const std::complex* x, IntegerForBlasType incx, const std::complex* y, IntegerForBlasType incy, std::complex* a, IntegerForBlasType lda)
	{
		cher2_(&uplo, &n, &alpha, x, &incx, y, &incy, a, &lda);
	}
	inline void HER2(char uplo, IntegerForBlasType n, const std::complex& alpha, const std::complex* x, IntegerForBlasType incx, const std::complex* y, IntegerForBlasType incy, std::complex* a, IntegerForBlasType lda)
	{
		zher2_(&uplo, &n, &alpha, x, &incx, y, &incy, a, &lda);
	}
	// *****************************************************************************
	inline void HPR2(char uplo, IntegerForBlasType n, const std::complex& alpha, const std::complex* x, IntegerForBlasType incx, const std::complex* y, IntegerForBlasType incy, std::complex* ap)
	{
		chpr2_(&uplo, &n, &alpha, x, &incx, y, &incy, ap);
	}
	inline void HPR2(char uplo, IntegerForBlasType n, const std::complex& alpha, const std::complex* x, IntegerForBlasType incx, const std::complex* y, IntegerForBlasType incy, std::complex* ap)
	{
		zhpr2_(&uplo, &n, &alpha, x, &incx, y, &incy, ap);
	}
	// *****************************************************************************
	inline void SYR(char uplo, IntegerForBlasType n, const float& alpha, const float* x, IntegerForBlasType incx, float* a, IntegerForBlasType lda)
	{
		ssyr_(&uplo, &n, &alpha, x, &incx, a, &lda);
	}
	inline void SYR(char uplo, IntegerForBlasType n, const double& alpha, const double* x, IntegerForBlasType incx, double* a, IntegerForBlasType lda)
	{
		dsyr_(&uplo, &n, &alpha, x, &incx, a, &lda);
	}
	// ****************************************************************************
	inline void SPR(char uplo, IntegerForBlasType n, const float& alpha, const float* x, IntegerForBlasType incx, float* ap)
	{
		sspr_(&uplo, &n, &alpha, x, &incx, ap);
	}
	inline void SPR(char uplo, IntegerForBlasType n, const double& alpha, const double* x, IntegerForBlasType incx, double* ap)
	{
		dspr_(&uplo, &n, &alpha, x, &incx, ap);
	}
	// ****************************************************************************
	inline void SYR2(char uplo, IntegerForBlasType n, const float& alpha, const float* x,

	    IntegerForBlasType incx,
	    const float* y,
	    IntegerForBlasType incy,
	    float* a,
	    IntegerForBlasType lda)
	{
		ssyr2_(&uplo, &n, &alpha, x, &incx, y, &incy, a, &lda);
	}
	inline void SYR2(char uplo, IntegerForBlasType n, const double& alpha, const double* x,

	    IntegerForBlasType incx,
	    const double* y,
	    IntegerForBlasType incy,
	    double* a,
	    IntegerForBlasType lda)
	{
		dsyr2_(&uplo, &n, &alpha, x, &incx, y, &incy, a, &lda);
	}
	// ****************************************************************************
	inline void SPR2(char uplo, IntegerForBlasType n, const float& alpha, const float* x,

	    IntegerForBlasType incx,
	    const float* y,
	    IntegerForBlasType incy,
	    float* ap)
	{
		sspr2_(&uplo, &n, &alpha, x, &incx, y, &incy, ap);
	}
	inline void SPR2(char uplo, IntegerForBlasType n, const double& alpha, const double* x,

	    IntegerForBlasType incx,
	    const double* y,
	    IntegerForBlasType incy,
	    double* ap)
	{
		dspr2_(&uplo, &n, &alpha, x, &incx, y, &incy, ap);
	}

	// ****************************************************************************

	inline void AXPY(IntegerForBlasType size, const float& a, const float* x, IntegerForBlasType sx, float* y, IntegerForBlasType sy)
	{
		saxpy_(&size, &a, x, &sx, y, &sy);
	}

	inline void AXPY(IntegerForBlasType size, const double& a, const double* x, IntegerForBlasType sx, double* y, IntegerForBlasType sy)
	{
		daxpy_(&size, &a, x, &sx, y, &sy);
	}

	inline void AXPY(IntegerForBlasType size, const std::complex& a, const std::complex* x, IntegerForBlasType sx,

	    std::complex* y,
	    IntegerForBlasType sy)
	{
		caxpy_(&size, &a, x, &sx, y, &sy);
	}

	inline void AXPY(IntegerForBlasType size, const std::complex& a, const std::complex* x, IntegerForBlasType sx,

	    std::complex* y,
	    IntegerForBlasType sy)
	{
		zaxpy_(&size, &a, x, &sx, y, &sy);
	}
	// ----------------------------------------------------------------------------
	inline void COPY(IntegerForBlasType size, const float* x, IntegerForBlasType sx, float* y, IntegerForBlasType sy)
	{
		scopy_(&size, x, &sx, y, &sy);
	}

	inline void COPY(IntegerForBlasType size, const double* x, IntegerForBlasType sx, double* y, IntegerForBlasType sy)
	{
		dcopy_(&size, x, &sx, y, &sy);
	}

	inline void COPY(IntegerForBlasType size, const std::complex* x, IntegerForBlasType sx, std::complex* y, IntegerForBlasType sy)
	{
		ccopy_(&size, x, &sx, y, &sy);
	}

	inline void COPY(IntegerForBlasType size, const std::complex* x, IntegerForBlasType sx, std::complex* y, IntegerForBlasType sy)
	{
		zcopy_(&size, x, &sx, y, &sy);
	}
	// ----------------------------------------------------------------------------
	inline void SCAL(IntegerForBlasType size, const float& a, float* y, IntegerForBlasType sy)
	{
		sscal_(&size, &a, y, &sy);
	}

	inline void SCAL(IntegerForBlasType size, const double& a, double* y, IntegerForBlasType sy)
	{
		dscal_(&size, &a, y, &sy);
	}

	inline void SCAL(IntegerForBlasType size, const std::complex& a, std::complex* y, IntegerForBlasType sy)
	{
		cscal_(&size, &a, y, &sy);
	}

	inline void SCAL(IntegerForBlasType size, const std::complex& a, std::complex* y, IntegerForBlasType sy)
	{
		zscal_(&size, &a, y, &sy);
	}
} /* namespace BLAS */
} /* namespace psimag */

#endif /* PSIMAG_BLAS */
PsimagLite-3.06/src/BitManip.h000066400000000000000000000023131446452427400161560ustar00rootroot00000000000000#ifndef BIT_MANIP_H
#define BIT_MANIP_H
#include "AllocatorCpu.h"

namespace PsimagLite
{
namespace BitManip
{
	// Counting bits set, Brian Kernighan's way
	typedef unsigned int long WordType;
	inline SizeType countKernighan(WordType v)
	{
		SizeType c = 0; // c accumulates the total bits set in v
		for (; v; c++)
			v &= v - 1; // clear the least significant bit set
		return c;
	}

	inline int count(WordType b)
	{
#if (ULONG_MAX == 0xfffffffful)
		b = (0x55555555 & b) + (0x55555555 & (b >> 1));
		b = (0x33333333 & b) + (0x33333333 & (b >> 2));
		b = (0x0f0f0f0f & b) + (0x0f0f0f0f & (b >> 4));
		b = (0x00ff00ff & b) + (0x00ff00ff & (b >> 8));
		b = (0x0000ffff & b) + (0x0000ffff & (b >> 16));

		return (int)b;
#else
		b = (0x5555555555555555 & b) + (0x5555555555555555 & (b >> 1));
		b = (0x3333333333333333 & b) + (0x3333333333333333 & (b >> 2));
		b = (0x0f0f0f0f0f0f0f0f & b) + (0x0f0f0f0f0f0f0f0f & (b >> 4));
		b = (0x00ff00ff00ff00ff & b) + (0x00ff00ff00ff00ff & (b >> 8));
		b = (0x0000ffff0000ffff & b) + (0x0000ffff0000ffff & (b >> 16));
		b = (0x00000000ffffffff & b) + (0x00000000ffffffff & (b >> 32));

		return (int)b;
#endif
	}

} // namespace BitManip

} // namespace PsimagLite

#endif // BIT_MANIP_H
PsimagLite-3.06/src/CMakeLists.txt000066400000000000000000000004701446452427400170440ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.4)
project(PsimagLite)

add_library(PsimagLite STATIC MersenneTwister.cpp Matrix.cpp Mpi.cpp ApplicationInfo.cpp Concurrency.cpp ProgressIndicator.cpp MemResolv.cpp PsimagLite.cpp PsiBase64.cpp SpecialFunctions.cpp)

target_link_libraries( PsimagLite ${CMAKE_THREAD_LIBS_INIT} )
PsimagLite-3.06/src/CanonicalExpression.h000066400000000000000000000115741446452427400204330ustar00rootroot00000000000000#ifndef PSI_CANONICAL_EXPRESSION_H
#define PSI_CANONICAL_EXPRESSION_H
#include "PsimagLite.h"
#include "QuasiCanonical.h"

namespace PsimagLite
{

template 
class AssignAndDestroy
{

public:

	typedef typename ItemSpecType::ResultType T;
	typedef typename ItemSpecType::ComplexOrRealType ComplexOrRealType;

	AssignAndDestroy(const T& t)
	    : t_(t)
	{
	}

	void assignBackward(T& t2) const { t2 = t_; }

	void assign(const AssignAndDestroy& t2) { t_ = t2.t_; }

	void plusBackward(T& t2) const { t2 += t_; }

	void multiply(const AssignAndDestroy& t2) { t_ *= (t2.t_); }

	void multiplyScalar(const ComplexOrRealType& scalar) { t_ *= scalar; }

	const bool isEmpty() const { return ItemSpecType::isEmpty(t_); }

	const bool metaEqual(const T& t2) const
	{
		return ItemSpecType::metaEqual(t_, t2);
	}

	static bool metaEqual(const AssignAndDestroy& t1,
	    const AssignAndDestroy& t2)
	{
		return ItemSpecType::metaEqual(t1.t_, t2.t_);
	}

private:

	T t_;
};

template >
class CanonicalExpression
{

	typedef typename ItemSpecType::ResultType ResultType;
	typedef typename ItemSpecType::ComplexOrRealType ComplexOrRealType;
	typedef typename ItemSpecType::AuxiliaryType AuxiliaryType;
	typedef typename Real::Type RealType;
	typedef Vector::Type VectorStringType;
	typedef QuasiCanonical QuasiCanonicalType;

public:

	CanonicalExpression(const ItemSpecType& itemSpec)
	    : itemSpec_(itemSpec)
	{
	}

	bool operator()(ResultType& result, String expr, const ResultType& resultEmpty, AuxiliaryType& aux) const
	{
		// canonical expressions only for now
		// expr --> exprCanonical
		QuasiCanonicalType quasiCanonical(expr);
		// String exprCanonical = expr; // canonicalize here
		// VectorStringType vecStr;
		const SizeType numberOfTerms = quasiCanonical.numberOfTerms();

		for (SizeType i = 0; i < numberOfTerms; ++i) {
			AssignAndDestroyType assignAndDestroy(
			    resultEmpty); // t_ = resultEmpty
			bool isNotEmpty = procCanonicalTerm(
			    assignAndDestroy, quasiCanonical, i, aux);
			if (!isNotEmpty)
				continue;
			if (!assignAndDestroy.metaEqual(result))
				err("CanonicalExpression: metas not equal\n");

			if (i == 0)
				assignAndDestroy.assignBackward(
				    result); // result = t_;
			else
				assignAndDestroy.plusBackward(
				    result); // result += t_;
		}

		return (ItemSpecType::isEmpty(result)) ? false : true;
	}

	template 
	static std::pair replaceAll(String str, String label, T value)
	{
		std::pair boolString(true, str);

		bool retFlag = false;
		while (boolString.first) {
			boolString = replaceOne(boolString.second, label, value);
			retFlag |= boolString.first;
		};

		return std::pair(retFlag, boolString.second);
	}

	template 
	static std::pair replaceOne(String str, String label, T value)
	{
		// find one occurrence
		size_t x = str.find(label);
		if (x == String::npos)
			return std::pair(false, str);

		String ret = (x == 0) ? "" : str.substr(0, x);
		ret += ttos(value);

		ret += str.substr(x + label.length(),
		    str.length() - x - label.length());

		return std::pair(true, ret);
	}

private:

	bool procCanonicalTerm(AssignAndDestroyType& assignAndDestroy,
	    QuasiCanonicalType& quasiCanonical,
	    SizeType ind,
	    AuxiliaryType& aux) const
	{
		String termCanonical = quasiCanonical.term(ind);
		ComplexOrRealType factor = 1.0;
		VectorStringType vecStr;
		split(vecStr, termCanonical, "*");

		for (SizeType i = 0; i < vecStr.size(); ++i) {
			procCanonicalFactor(assignAndDestroy, factor, vecStr[i], quasiCanonical, aux);
		}

		if (assignAndDestroy.isEmpty())
			return false;

		assignAndDestroy.multiplyScalar(factor);
		return true;
	}

	void procCanonicalFactor(AssignAndDestroyType& prev,
	    ComplexOrRealType& factor,
	    String termStr,
	    QuasiCanonicalType& quasiCanonical,
	    AuxiliaryType& aux) const
	{
		bool isCaScalar = QuasiCanonicalType::isRealScalar(termStr);
		if (isCaScalar) {
			const ComplexOrRealType f = PsimagLite::atof(termStr);
			factor *= f;
			return;
		}

		bool isPureCmplx = QuasiCanonicalType::isPureComplex(termStr);
		if (isPureCmplx) {
			const ComplexOrRealType f = QuasiCanonicalType::pureComplex(termStr);
			factor *= f;
			return;
		}

		const int ind = quasiCanonical.scalarIndex(termStr);
		if (ind >= 0) {
			const ComplexOrRealType f = quasiCanonical.scalarFromIndex(ind);
			factor *= f;
			return;
		}

		AssignAndDestroyType term(itemSpec_(termStr, aux));
		if (prev.isEmpty()) {
			prev.assign(term); // prev = term
			return;
		}

		if (!AssignAndDestroyType::metaEqual(term, prev))
			err("CanonicalExpression: metas not equal\n");

		prev.multiply(term); // prev *= term
	}

	const ItemSpecType& itemSpec_;
};
} // namespace PsimagLite
#endif // PSI_CANONICAL_EXPRESSION_H
PsimagLite-3.06/src/ChebyshevFunction.h000066400000000000000000000023411446452427400201020ustar00rootroot00000000000000
/*
// BEGIN LICENSE BLOCK
Copyright (c) 2011, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file ChebyshevFunction.h
 *
 * The Chebyshev function
 *
 */

#ifndef CHEBYSHEV_FUNCTION_H
#define CHEBYSHEV_FUNCTION_H
#include "TypeToString.h"
#include 

namespace PsimagLite
{
template 
class ChebyshevFunction
{

public:

	RealType operator()(int m, const RealType& x) const
	{
		if (m == 0)
			return 1;

		if (m == 1)
			return x;

		if (m & 1) {
			int p = (m - 1) / 2;
			return (2 * this->operator()(p, x) * this->operator()(p + 1, x) - x);
		}

		int pp = m / 2;
		RealType tmp = this->operator()(pp, x);
		return (2 * tmp * tmp - 1);
	}
}; // class ChebyshevFunction

} // namespace PsimagLite
/*@}*/
#endif // CHEBYSHEV_FUNCTION_H
PsimagLite-3.06/src/ChebyshevFunctionExplicit.h000066400000000000000000000032471446452427400216120ustar00rootroot00000000000000
/*
// BEGIN LICENSE BLOCK
Copyright (c) 2011, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file ChebyshevFunctionExplicit.h
 *
 * The Chebyshev function with caching
 *
 */

#ifndef CHEBYSHEV_F_EXPLICIT_H
#define CHEBYSHEV_F_EXPLICIT_H
#include "ChebyshevFunction.h"
#include 

namespace PsimagLite
{
template 
class ChebyshevFunctionExplicit
{

public:

	RealType operator()(int m, const RealType& x) const
	{

		switch (m) {
		case 0:
			return 1;
		case 1:
			return x;
		}

		RealType x1 = x * x;
		switch (m) {
		case 2:
			return 2 * x1 - 1;
		case 3:
			return 4 * x1 * x - 3 * x;
		case 4:
			return 8 * x1 * x1 - 8 * x1 + 1;
		case 5:
			return 16 * x1 * x1 * x - 20 * x1 * x + 5 * x;
		}

		RealType x2 = x1 * x1;
		switch (m) {
		case 6:
			return 32 * x2 * x1 - 48 * x2 + 18 * x1 - 1;
		case 7:
			return 64 * x2 * x1 * x - 112 * x2 * x + 56 * x1 * x - 7 * x;
		}

		if (m & 1) {
			int p = (m - 1) / 2;
			return (2 * this->operator()(p, x) * this->operator()(p + 1, x) - x);
		}

		int pp = m / 2;
		RealType tmp = this->operator()(pp, x);
		return (2 * tmp * tmp - 1);
	}
}; // class ChebyshevFunctionExplicit
} // namespace PsimagLite
/*@}*/
#endif // CHEBYSHEV_F_EXPLICIT_H
PsimagLite-3.06/src/ChebyshevSerializer.h000066400000000000000000000147311446452427400204340ustar00rootroot00000000000000
/*
// BEGIN LICENSE BLOCK
Copyright (c) 2011, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file ChebyshevSerializer.h
 *
 * This class saves the moments of a Chebyshev expansion so that
 * they can later be processed (with KernelPolynomial, for example)
 *
 * The interface follows ContinuedFraction so that it can be
 * used interchangably
 *
 */

#ifndef CHEBYSHEV_SERIALIZER_H
#define CHEBYSHEV_SERIALIZER_H
#include "ChebyshevFunction.h"
#include "Io/IoSelector.h"
#include "Io/IoSimple.h"
#include "ParametersForSolver.h"
#include "PlotParams.h"
#include "ProgressIndicator.h"
#include "Random48.h"
#include "TridiagonalMatrix.h"
#include "TypeToString.h"
#include 
#include 
#include 
#include 

namespace PsimagLite
{

template 
struct KernelPolynomialParameters {

	enum { JACKSON,
		LORENTZ,
		DIRICHLET };

	KernelPolynomialParameters(SizeType type1, SizeType cutoff1, const RealType& lambda1)
	    : type(type1)
	    , cutoff(cutoff1)
	    , lambda(lambda1)
	{
	}

	SizeType type;
	SizeType cutoff;
	RealType lambda;
}; // struct KernelPolynomialParameters

template 
class ChebyshevSerializer
{

	typedef typename VectorType_::value_type VectorElementType;
	typedef typename Real::Type RealType;

	static const String stringMarker_;

public:

	typedef VectorType_ VectorType;
	typedef typename VectorType::value_type FieldType;
	typedef Matrix MatrixType;
	typedef
	    typename Vector>::Type PlotDataType;
	typedef PlotParams PlotParamsType;
	typedef ParametersForSolver ParametersType;
	typedef KernelPolynomialParameters KernelParametersType;
	typedef TridiagonalMatrix TridiagonalMatrixType;
	typedef typename TridiagonalMatrixType::VectorRealType VectorRealType;

	ChebyshevSerializer(const TridiagonalMatrixType& ab,
	    const ParametersType& params)
	    : progress_("ChebyshevSerializer")
	    , moments_(ab)
	    , params_(params)
	{
	}

	template 
	ChebyshevSerializer(IoInputType& io)
	    : progress_("ChebyshevSerializer")
	    , params_(io, "#Chebyshev")
	{
		VectorRealType tmp;
		io.read(tmp, "#ChebyshevMoments");
		SizeType n = tmp.size() / 2;
		for (SizeType i = 0; i < n; ++i) {
			moments_.a(i) = tmp[2 * i];
			moments_.b(i) = tmp[2 * i + 1];
		}
	}

	template 
	void write(SomeIoOutputType&, String) const
	{
		String name(typeid(SomeIoOutputType).name());
		std::cerr << "WARNING: cannot save ChebyshevSerializer";
		std::cerr << "to output type " << name << "\n";
	}

	void write(IoSimple::Out& io, String) const
	{
		io.write(0, stringMarker_);
		io.write(params_.Eg, "#ChebyshevEnergy=");
		io.write(params_.oneOverA, "#ChebyshevOneOverA=");
		io.write(params_.b, "#ChebyshevB=");
		io.write(moments_, "#ChebyshevMoments");
	}

	static const String& stringMarker() { return stringMarker_; }

	void plot(PlotDataType& result, const PlotParamsType& params, const KernelParametersType& kernelParams) const
	{
		SizeType cutoff = kernelParams.cutoff;
		if (cutoff == 0 || moments_.size() < cutoff)
			cutoff = moments_.size();
		VectorRealType gn(cutoff, 1.0);
		initKernel(gn, kernelParams);

		VectorRealType gnmun(gn.size());
		computeGnMuN(gnmun, gn);

		SizeType counter = 0;
		SizeType n = SizeType((params.omega2 - params.omega1) / params.deltaOmega);
		if (result.size() == 0)
			result.resize(n);
		RealType offset = params_.Eg;
		std::cerr << "gn[0]=" << gn[0] << " gn[5]=" << gn[5] << "\n";
		for (RealType omega = params.omega1; omega < params.omega2;
		     omega += params.deltaOmega) {
			RealType x = (omega + offset - params_.b) * params_.oneOverA;

			RealType den = (x > 1.0 || x < -1.0) ? 0.0 : sqrt(1.0 - x * x);
			RealType tmp = (fabs(den) > 1e-6) ? calcF(x, gnmun) / den : 0.0;
			std::pair p(omega, tmp);
			result[counter++] = p;

			if (counter >= result.size())
				break;
		}
	}

	//! Cases:
	//! (1) < phi0|A (z+(E0-e_k))^{-1}|A^\dagger|phi0> and
	//! (2) < phi0|A^\dagger (z-(E0-e_k))^{-1}|A|phi0>
	//! (There are actually 4 cases for the off-diagonal gf because
	//! A has two cases:
	//! (1) A = c_i + c_j and
	//! (2) A = c_i - c_j
	RealType iOfOmega(const RealType&, RealType, int) const

	{
		throw RuntimeError("iOfOmega: unimplemented\n");
	}

private:

	RealType calcF(const RealType& x, const VectorRealType& gnmn) const
	{
		RealType sum = 0.5 * gnmn[0];
		for (SizeType i = 1; i < gnmn.size(); i++)
			sum += gnmn[i] * chebyshev_(i, x);
		return 2.0 * sum;
	}

	void computeGnMuN(VectorRealType& gnmn, VectorRealType& gn) const
	{
		for (SizeType i = 0; i < gnmn.size(); ++i) {
			const SizeType j = (i & 1) ? (i - 1) / 2 : i / 2;
			const RealType& tmp = (i & 1) ? moments_.b(j) : moments_.a(j);
			gnmn[i] = tmp * gn[i];
		}
	}

	void initKernel(VectorRealType& gn,
	    const KernelParametersType& kernelParams) const
	{
		switch (kernelParams.type) {
		case KernelParametersType::JACKSON:
			initKernelJackson(gn);
			break;
		case KernelParametersType::LORENTZ:
			initKernelLorentz(gn, kernelParams.lambda);
			break;
		case KernelParametersType::DIRICHLET:
			break;
		default:
			assert(false);
		}
	}

	void initKernelJackson(VectorRealType& gn) const
	{
		SizeType nPlus1 = gn.size() + 1;
		RealType cot1 = 1.0 / tan(M_PI / nPlus1);
		for (SizeType i = 0; i < gn.size(); i++) {
			gn[i] = (nPlus1 - i) * cos(M_PI * i / nPlus1) + sin(M_PI * i / nPlus1) * cot1;
			gn[i] /= nPlus1;
		}
	}

	void initKernelLorentz(VectorRealType& gn, const RealType& lambda) const
	{
		RealType nreal = gn.size();
		RealType sinhlambda = sinh(lambda);
		for (SizeType i = 0; i < gn.size(); i++) {
			gn[i] = sinh(lambda * (1 - i / nreal)) / sinhlambda;
		}
	}

	ProgressIndicator progress_;
	TridiagonalMatrixType moments_;
	ParametersType params_;
	ChebyshevFunction chebyshev_;
}; // class ChebyshevSerializer

template 
const String ChebyshevSerializer::stringMarker_ = "#ChebyshevSerializerMarker";
} // namespace PsimagLite
/*@}*/
#endif // CHEBYSHEV_SERIALIZER_H
PsimagLite-3.06/src/ChebyshevSolver.h000066400000000000000000000250251446452427400175730ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/

/** \ingroup PsimagLite */
/*@{*/

/*! \file ChebyshevSolver.h
 *
 *  A class to represent a generic Lanczos Solver
 *
 */

#ifndef CHEBYSHEV_SOLVER_H_
#define CHEBYSHEV_SOLVER_H_
#include "ChebyshevSerializer.h"
#include "LanczosOrDavidsonBase.h"
#include "LanczosSolver.h"
#include "Matrix.h"
#include "ProgressIndicator.h"
#include "Random48.h"
#include "TridiagonalMatrix.h"
#include "TypeToString.h"
#include "Vector.h"

namespace PsimagLite
{

/** MatrixType must have the following interface:
 * RealType type to indicate the matrix type
 * rows() member function to indicate the rank of the matrix
 * matrixVectorProduct(typename Vector< RealType>::Type& x,const
 *        typename Vector< RealType>::Type& const y)
 *    member function that implements the operation x += Hy
 *
 * SolverParametersType is just a structure with a few things
 * like eMax, eMin, the spectrum bounds (needed to scale the Hamiltonian)
 * steps, the number of moments to compute, you can use
 * ParametersForSolver class, if you want.
 *
 */
template 
class ChebyshevSolver
{

	typedef LanczosOrDavidsonBase
	    NotBaseType;
	typedef typename SolverParametersType::RealType RealType;
	typedef LanczosVectors LanczosVectorsType;
	typedef typename LanczosVectorsType::DenseMatrixType DenseMatrixType;
	typedef typename LanczosVectorsType::DenseMatrixRealType
	    DenseMatrixRealType;
	typedef typename LanczosVectorsType::VectorVectorType VectorVectorType;

public:

	typedef SolverParametersType ParametersSolverType;
	typedef MatrixType_ MatrixType;
	typedef TridiagonalMatrix TridiagonalMatrixType;
	typedef typename VectorType::value_type VectorElementType;
	typedef ChebyshevSerializer PostProcType;
	typedef PsimagLite::Random48 RngType;

	enum { WITH_INFO = 1,
		DEBUG = 2,
		ALLOWS_ZERO = 4 };

	ChebyshevSolver(MatrixType const& mat, SolverParametersType& params)
	    : progress_("ChebyshevSolver")
	    , mat_(mat)
	    , params_(params)
	    , mode_(WITH_INFO)
	    , rng_(343311)
	    , lanczosVectors_(mat, params.lotaMemory, params.steps, NotBaseType::isReorthoEnabled(params))
	{
		params.steps = 400;
		setMode(params.options);
		computeAandB();
		PsimagLite::OstringStream msgg(std::cout.precision());
		PsimagLite::OstringStream::OstringStreamType& msg = msgg();
		msg << "Constructing... mat.rank=" << mat_.rows()
		    << " steps=" << params.steps;
		progress_.printline(msgg, std::cout);
	}

	void computeGroundState(RealType&, VectorType&)
	{
		unimplemented("computeGroundState");
	}

	void computeGroundState(RealType& gsEnergy, VectorType& z, const VectorType& initialVector)
	{
		if (mode_ & DEBUG) {
			computeGroundStateTest(gsEnergy, z, initialVector);
			return;
		}
		unimplemented("computeGroundState");
	}

	void buildDenseMatrix(DenseMatrixType&,
	    const TridiagonalMatrixType&) const
	{
		unimplemented("buildDenseMatrix");
	}

	void push(TridiagonalMatrixType& ab, const RealType& a, const RealType& b) const
	{
		ab.push_back(a);
		ab.push_back(b);
	}

	//! ab.a contains the even moments
	//! ab.b contains the odd moments
	void decomposition(const VectorType& initVector,
	    TridiagonalMatrixType& ab)
	{
		VectorType x(initVector.size(), 0.0);
		VectorType y = initVector;

		lanczosVectors_.prepareMemory(y.size(), lanczosVectors_.cols());
		ab.resize(2 * params_.steps, 0);
		SizeType cols = lanczosVectors_.cols();
		for (SizeType j = 0; j < cols; ++j) {
			if (lanczosVectors_.lotaMemory())
				lanczosVectors_.saveVector(y, j);

			RealType atmp = 0;
			RealType btmp = 0;
			oneStepDec(x, y, atmp, btmp, j);
			ab.a(j) = 2 * atmp - ab.a(0);
			ab.b(j) = 2 * btmp - ab.b(0);
		}

		// lanczosVectors_.resize(cols); <--- not needed because all
		// steps are performed
		//                                    and there is no early exit
		//                                    here
	}

	//! atmp = < phi_n | phi_n>
	//! btmp = < phi_n | phi_{n+1}>
	void oneStepDec(VectorType& x, VectorType& y, RealType& atmp, RealType& btmp, SizeType jind) const
	{
		bool isFirst = (jind == 0);
		VectorType z(x.size(), 0.0);
		mat_.matrixVectorProduct(z, y); // z+= Hy
		// scale matrix:
		z -= params_.b * y;
		z *= params_.oneOverA;

		RealType val = (isFirst) ? 1.0 : 2.0;

		atmp = 0.0;
		for (SizeType i = 0; i < mat_.rows(); i++)
			atmp += PsimagLite::real(y[i] * PsimagLite::conj(y[i]));

		for (SizeType i = 0; i < mat_.rows(); i++) {
			VectorElementType tmp = val * z[i] - x[i];
			x[i] = y[i];
			y[i] = tmp;
		}

		btmp = 0.0;
		for (SizeType i = 0; i < mat_.rows(); i++)
			btmp += PsimagLite::real(y[i] * PsimagLite::conj(x[i]));
	}

	SizeType steps() const { return params_.steps; }

	void lanczosVectorsSwap(DenseMatrixType& V)
	{
		DenseMatrixType* ptr = lanczosVectors_.data();
		if (!ptr)
			err("LanczosSolver::lanczosVectors() called but no "
			    "data stored\n");
		return ptr->swap(V);
	}

private:

	void unimplemented(const String& s) const
	{
		String s2("Hmmm...this ain't looking good...");
		s2 += String(__FILE__) + " " + ttos(__LINE__) + " ";
		s2 += s;
		throw RuntimeError(s);
	}

	void setMode(const String& options)
	{
		if (options.find("lanczosdebug") != String::npos)
			mode_ |= DEBUG;

		if (options.find("lanczosAllowsZero") != String::npos)
			mode_ |= ALLOWS_ZERO;
	}

	void info(RealType energyTmp, const VectorType& x, std::ostream& os)
	{
		RealType norma = norm(x);

		if (norma < 1e-5 || norma > 100) {
			std::cerr << "norma=" << norma << "\n";
			// throw RuntimeError("Norm\n");
		}

		PsimagLite::OstringStream msgg(std::cout.precision());
		PsimagLite::OstringStream::OstringStreamType& msg = msgg();
		msg << "Found Energy=" << energyTmp << " after "
		    << params_.steps;
		msg << " iterations, "
		    << " orig. norm=" << norma;
		progress_.printline(msgg, os);
	}

	//! only for debugging:
	void computeGroundStateTest(RealType& gsEnergy, VectorType& z, const VectorType& initialVector)
	{
		unimplemented("computeGroundStateTest");
	}

	class InternalMatrix
	{
	public:

		InternalMatrix(const MatrixType& mat)
		    : matx_(mat)
		    , y_(matx_.rows())
		{
		}

		SizeType rows() const { return matx_.rows(); }

		void matrixVectorProduct(VectorType& x,
		    const VectorType& y) const
		{
			for (SizeType i = 0; i < y_.size(); i++)
				y_[i] = -y[i];
			matx_.matrixVectorProduct(x, y_);
		}

		VectorElementType operator()(SizeType i, SizeType j) const
		{
			return matx_(i, j);
		}

	private:

		const MatrixType& matx_;
		mutable VectorType y_;
	}; // class InternalMatrix

	void computeAandB()
	{
		PsimagLite::OstringStream msgg(std::cout.precision());
		PsimagLite::OstringStream::OstringStreamType& msg = msgg();
		msg << "Asking LanczosSolver to compute spectrum bounds...";
		progress_.printline(msgg, std::cout);

		SolverParametersType params;
		InternalMatrix mat2(mat_);
		RealType eMax = 0;
		LanczosSolver
		    lanczosSolver2(mat2, params);

		VectorType z2(mat_.rows(), 0);
		VectorType init(z2.size());
		PsimagLite::fillRandom(init);
		lanczosSolver2.computeOneState(eMax, z2, init, 0);

		VectorType z(mat_.rows(), 0);
		LanczosSolver
		    lanczosSolver(mat_, params);
		RealType eMin = 0;
		lanczosSolver.computeOneState(eMin, z, init, 0);

		eMax = -eMax;
		eMax *= 3;
		eMin *= 3;
		assert(eMax - eMin > 1e-2);

		params_.oneOverA = 2.0 / (eMax - eMin);
		params_.b = (eMax + eMin) / 2;

		PsimagLite::OstringStream msgg2(std::cout.precision());
		PsimagLite::OstringStream::OstringStreamType& msg2 = msgg2();
		msg2 << "Spectrum bounds computed, eMax=" << eMax
		     << " eMin=" << eMin;
		progress_.printline(msgg2, std::cout);
	}

	ProgressIndicator progress_;
	MatrixType const& mat_;
	SolverParametersType& params_;
	SizeType mode_;
	RngType rng_;
	LanczosVectorsType lanczosVectors_;
	//! Scaling factors for the Chebyshev expansion
}; // class ChebyshevSolver
} // namespace PsimagLite
/*@}*/
#endif // CHEBYSHEV_SOLVER_H_
PsimagLite-3.06/src/CmplxOrReal.h000066400000000000000000000023421446452427400166450ustar00rootroot00000000000000#ifndef CMPLX_OR_REAL_H
#define CMPLX_OR_REAL_H
#include "Vector.h"

namespace PsimagLite
{

template 
class CpmlxOrReal
{
};

template 
class CpmlxOrReal
{

public:

	typedef std::complex ComplexType;

	CpmlxOrReal(String t)
	    : isImag_(false)
	    , value_(0)
	{

		const SizeType len = t.length();
		String buffer;
		for (SizeType i = 0; i < len; ++i) {
			if (t[i] == 'i') {
				if (isImag_)
					throw RuntimeError(
					    "More than one i found\n");
				isImag_ = true;
				continue;
			}

			buffer += t[i];
		}

		if (isImag_ && buffer == "")
			value_ = 1;
		else
			value_ = PsimagLite::atof(buffer);
	}

	ComplexType value() const
	{
		return (isImag_) ? ComplexType(0, value_) : value_;
	}

private:

	bool isImag_;
	RealType value_;
};

template 
class CpmlxOrReal
{

public:

	CpmlxOrReal(String t)
	    : value_(0)
	{
		bool isComplex = (t.find("i") != String::npos);
		if (isComplex)
			throw RuntimeError(
			    "i \\equiv sqrt(-1) found but code path is real\n");
		value_ = PsimagLite::atof(t);
	}

	RealType value() const { return value_; }

private:

	RealType value_;
};

} // namespace PsimagLite
#endif // CMPLX_OR_REAL_H
PsimagLite-3.06/src/CodeSectionParams.h000066400000000000000000000011671446452427400200240ustar00rootroot00000000000000#ifndef CODESECTION_PARAMS_H
#define CODESECTION_PARAMS_H
#include "AllocatorCpu.h"

namespace PsimagLite
{

struct CodeSectionParams {

	CodeSectionParams(SizeType threads)
	    : npthreads(threads)
	    , npthreadsLevelTwo(1)
	    , setAffinities(false)
	    , stackSize(0)
	{
	}

	CodeSectionParams(SizeType threads, SizeType nthreadsLevel2, bool a, size_t s)
	    : npthreads(threads)
	    , npthreadsLevelTwo(nthreadsLevel2)
	    , setAffinities(a)
	    , stackSize(s)
	{
	}

	SizeType npthreads;
	SizeType npthreadsLevelTwo;
	bool setAffinities;
	size_t stackSize;
};
} // namespace PsimagLite
#endif // CODESECTION_PARAMS_H
PsimagLite-3.06/src/Complex.h000066400000000000000000000047101446452427400160650ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************

*/

#ifndef PSICOMPLEX_H_
#define PSICOMPLEX_H_

#include "../loki/TypeTraits.h"
#include "AllocatorCpu.h"
#include 

namespace PsimagLite
{

template 
class Real
{
public:

	typedef ComplexOrRealType Type;
};

template 
class Real>
{
public:

	typedef RealType Type;
};

template 
class IsComplexNumber
{
public:

	enum OpaqueEnum { True = false };
};

template 
class IsComplexNumber>
{
public:

	enum OpaqueEnum { True = Loki::TypeTraits::isArith };
};

template 
struct IsNumber {
	enum {
		True = (IsComplexNumber::True || Loki::TypeTraits::isArith)
	};
};

template 
typename EnableIf::isArith, T>::Type real(T t)
{
	return t;
}

template 
typename EnableIf::isArith, T>::Type
real(const std::complex& t)
{
	return std::real(t);
}

template 
typename EnableIf::isArith, T>::Type imag(T)
{
	return 0.0;
}

template 
typename EnableIf::isArith, T>::Type
imag(const std::complex& t)
{
	return std::imag(t);
}

template 
typename EnableIf::isFloat, T>::Type conj(T t)
{
	return t;
}

template 
typename EnableIf::isFloat, std::complex>::Type
conj(const std::complex& t)
{
	return std::conj(t);
}

template 
typename EnableIf::isArith, T>::Type norm(T t)
{
	return std::fabs(t);
}

template 
typename EnableIf::isFloat, T>::Type
norm(const std::complex& t)
{
	return std::norm(t);
}
} // namespace PsimagLite

namespace std
{
template 
typename PsimagLite::EnableIf::isFloat,
    std::complex>::Type
operator*(int x, const std::complex& y)
{
	return std::complex(real(y) * x, imag(y) * x);
}
} // namespace std

#endif // PSICOMPLEX_H_
PsimagLite-3.06/src/Concurrency.cpp000066400000000000000000000003121446452427400172750ustar00rootroot00000000000000#include "Concurrency.h"

namespace PsimagLite
{

SizeType Concurrency::mode = 0;
LabelDisabled Concurrency::mpiDisabled_;
CodeSectionParams Concurrency::codeSectionParams(1);
} // namespace PsimagLite
PsimagLite-3.06/src/Concurrency.h000066400000000000000000000166341446452427400167600ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file Concurrency.h
 *
 */
#ifndef CONCURRENCY_HEADER_H
#define CONCURRENCY_HEADER_H
#include "CodeSectionParams.h"
#include "FloatingPoint.h"
#include "LAPACK.h"
#include "LabelDisabled.h"
#include "Mpi.h"
#include "Vector.h"
#include 
#include 
#include 
#include 

namespace PsimagLite
{

class Concurrency
{

	typedef LabelDisabled MpiDisabledType;

public:

	static SizeType mode;
	static CodeSectionParams codeSectionParams;

#ifndef USE_PTHREADS

	typedef int MutexType;
	typedef SizeType PthreadtType;

	static void mutexLock(MutexType*) { }

	static void mutexUnlock(MutexType*) { }

	static void mutexInit(MutexType*) { }

	static void mutexDestroy(MutexType*) { }

	static PthreadtType threadSelf() { return 0; }

#else

#include 

	typedef pthread_mutex_t MutexType;
	typedef pthread_t PthreadtType;

	static void mutexInit(MutexType* mutex)
	{
		if (pthread_mutex_init(mutex, 0) != 0)
			std::cerr << "WARNING: mutexInit returned non zero\n";
	}

	static void mutexDestroy(MutexType* mutex)
	{
		if (pthread_mutex_destroy(mutex) != 0)
			std::cerr
			    << "WARNING: mutexDestroy returned non zero\n";
	}

	static void mutexLock(MutexType* mutex)
	{
		if (pthread_mutex_lock(mutex) != 0)
			std::cerr << "WARNING: mutexLock returned non zero\n";
	}

	static void mutexUnlock(MutexType* mutex)
	{
		if (pthread_mutex_unlock(mutex) != 0)
			std::cerr << "WARNING: mutexUnlock returned non zero\n";
	}

	// DON'T EVEN think of using this as a thread id
	// This ISN'T 0, 1, 2, ...
	// it's a rather large number
	// Only assured thing is its uniqueness per PROCESS
	static PthreadtType threadSelf() { return pthread_self(); }

#endif

	enum { SERIAL = 0,
		PTHREADS = 1,
		MPI = 2,
		PTHREADS_AND_MPI = 3 };

	static SizeType storageSize(SizeType npthreads)
	{
		switch (mode) {
		case SERIAL:
			assert(npthreads == 1);
		case PTHREADS:
		case PTHREADS_AND_MPI:
			return npthreads;
		case MPI:
			return 1;
		}
		throw RuntimeError("storageSize: wrong mode\n");
	}

	static SizeType storageIndex(SizeType threadNum)
	{
		switch (mode) {
		case SERIAL:
			assert(threadNum == 0);
		case PTHREADS:
		case PTHREADS_AND_MPI:
			return threadNum;
		case MPI:
			return 0;
		}
		throw RuntimeError("storageIndex: wrong mode\n");
	}

	Concurrency(int* argc, char*** argv, size_t nthreads)
	{
		FloatingPoint::enableExcept();
		codeSectionParams.npthreads = nthreads;
		codeSectionParams.npthreadsLevelTwo = 1;
		mode = 0;
#ifdef USE_PTHREADS
		mode |= 1;
		if (!psimag::LAPACK::isThreadSafe())
			std::cerr
			    << "WARNING: You LAPACK might not be thread safe\n";
#else
		if (nthreads != 1)
			throw RuntimeError("nthreads>1 but no USE_PTHREADS "
					   "support compiled\n");
#endif

		MPI::init(argc, argv);
		MPI::info(std::cout);
		MPI::version(std::cout);

		if (MPI::hasMpi())
			mode |= 2;
	}

	~Concurrency() { MPI::finalize(); }

	static bool root(MPI::CommType comm = MPI::COMM_WORLD)
	{
		return (MPI::commRank(comm) == 0);
	}

	static SizeType nprocs(MPI::CommType comm = MPI::COMM_WORLD)
	{
		return MPI::commSize(comm);
	}

	static SizeType rank(MPI::CommType comm = MPI::COMM_WORLD)
	{
		return MPI::commRank(comm);
	}

	static bool hasMpi() { return (mode & MPI); }

	static bool hasPthreads() { return (mode & PTHREADS); }

	static void mpiDisable(String label)
	{
		if (!hasMpi())
			return;
		mpiDisabled_.disable(label);
	}

	static void mpiDisableIfNeeded(SizeType& mpiRank, SizeType& blockSize, String label, SizeType total)
	{
		if (!hasMpi())
			return;
		if (!mpiDisabled_(label))
			return;
		mpiRank = 0;
		blockSize = total;
		if (!hasPthreads())
			return;
		String str(__FILE__);
		str += " mpiDisableIfNeeded label = " + label + "\n";
		throw RuntimeError(str);
	}

	static bool isMpiDisabled(String label)
	{
		if (!hasMpi())
			return false;
		return mpiDisabled_(label);
	}

	static void setOptions(const CodeSectionParams& cs)
	{
		codeSectionParams = cs;
		if (codeSectionParams.npthreads == 1 && codeSectionParams.npthreadsLevelTwo == 1)
			return;

#ifndef USE_PTHREADS
		PsimagLite::String message1(__FILE__);
		message1 += " FATAL: You are requesting nthreads > 0 but you ";
		message1 += "did not compile with USE_PTHREADS enabled\n";
		message1 += " Either set Threads=1 in the input file (you won't ";
		message1 += "have threads though) or\n";
		message1 += " add -DUSE_PTHREADS to the CPP_FLAGS in your Makefile ";
		message1 += "and recompile\n";
		throw PsimagLite::RuntimeError(message1.c_str());
#else
		std::cout << "Concurrency::npthreads="
			  << codeSectionParams.npthreads << "\n";
		std::cout << "Concurrency::npthreads2="
			  << codeSectionParams.npthreadsLevelTwo << "\n";
		std::cout << "Concurrency::setAffinitiesDefault="
			  << codeSectionParams.setAffinities << "\n";
#endif
	}

private:

	static MpiDisabledType mpiDisabled_;
};

} // namespace PsimagLite

/*@}*/
#endif
PsimagLite-3.06/src/ContinuedFraction.h000066400000000000000000000143341446452427400200770ustar00rootroot00000000000000
/*
// BEGIN LICENSE BLOCK
Copyright (c) 2009 , UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file ContinuedFraction.h
 *
 * A continued fraction as explained in, e.g.,
 * E. Dagotto, Rev. Mod. Phys., 66, 763, (2004).
 */

#ifndef CONTINUED_FRACTION_H
#define CONTINUED_FRACTION_H
#include "Complex.h"
#include "FreqEnum.h"
#include "Io/IoSimple.h"
#include "ParametersForSolver.h"
#include "PlotParams.h"
#include "ProgressIndicator.h"
#include "Random48.h"
#include "TypeToString.h"
#include 
#include 

namespace PsimagLite
{
template 
class ContinuedFraction
{
public:

	typedef TridiagonalMatrixType_ TridiagonalMatrixType;
	typedef typename TridiagonalMatrixType::value_type MatrixElementType;
	typedef typename Real::Type RealType;
	typedef typename std::complex ComplexType;
	typedef typename TridiagonalMatrixType::value_type FieldType;
	typedef Matrix MatrixType;
	typedef Matrix MatrixRealType;
	typedef typename Vector>::Type
	    PlotDataType;
	typedef PlotParams PlotParamsType;
	typedef ParametersForSolver ParametersType;

	ContinuedFraction(const TridiagonalMatrixType& ab,
	    const ParametersType& params)
	    : progress_("ContinuedFraction")
	    , freqEnum_(FREQ_REAL)
	    , ab_(ab)
	    , Eg_(params.Eg)
	    , weight_(params.weight)
	    , isign_(params.isign)
	{
		diagonalize();
	}

	ContinuedFraction(FreqEnum freqEnum = FREQ_REAL)
	    : progress_("ContinuedFraction")
	    , freqEnum_(freqEnum)
	    , ab_()
	    , Eg_(0)
	    , weight_(0)
	    , isign_(1)
	{
	}

	ContinuedFraction(IoSimple::In& io)
	    : progress_("ContinuedFraction")
	    , freqEnum_(FREQ_REAL)
	    , ab_(io)
	{
		String f;
		try {
			io.readline(f, "#FreqEnum=");
		} catch (std::exception& e) {
			std::cerr
			    << "ContinuedFraction: FreqEnum assumed REAL\n";
			f = "Real";
			io.rewind();
		}

		if (f == "Matsubara")
			freqEnum_ = FREQ_MATSUBARA;

		io.readline(weight_, "#CFWeight=");
		io.readline(Eg_, "#CFEnergy=");
		io.readline(isign_, "#CFIsign=");
		io.read(eigs_, "#CFEigs");
		io.read(intensity_, "#CFIntensities");
		diagonalize();
	}

	template 
	void write(SomeIoOutputType&, String) const
	{
		String name(typeid(SomeIoOutputType).name());
		std::cerr << "WARNING: cannot save ContinuedFraction";
		std::cerr << "to output type " << name << "\n";
	}

	void write(IoSimple::Out& io, String) const
	{
		io.setPrecision(12);
		ab_.write(io);

		String f = (freqEnum_ == FREQ_MATSUBARA) ? "Matsubara" : "Real";
		io.write(" ", "#FreqEnum=" + f);

		io.write(weight_, "#CFWeight");

		io.write(Eg_, "#CFEnergy");

		io.write(isign_, "#CFIsign");

		io.write(eigs_, "#CFEigs");
		io.write(intensity_, "#CFIntensities");
	}

	void set(const TridiagonalMatrixType& ab, const RealType& Eg, RealType weight, int isign)
	{
		ab_ = ab;
		Eg_ = Eg;
		weight_ = weight;
		isign_ = isign;

		diagonalize();
	}

	void plot(PlotDataType& result, const PlotParamsType& params) const
	{
		if (freqEnum_ == FREQ_MATSUBARA || params.numberOfMatsubaras > 0) {
			plotMatsubara(result, params);
			return;
		}

		if (freqEnum_ == FREQ_REAL || params.numberOfMatsubaras == 0) {
			plotReal(result, params);
		}
	}

	void plotReal(PlotDataType& result, const PlotParamsType& params) const
	{
		SizeType counter = 0;
		SizeType n = SizeType((params.omega2 - params.omega1) / params.deltaOmega);
		if (result.size() == 0)
			result.resize(n);
		for (RealType omega = params.omega1; omega < params.omega2;
		     omega += params.deltaOmega) {
			ComplexType z(omega, params.delta);
			ComplexType res = iOfOmega(z, Eg_, isign_);
			std::pair p(omega, res);
			result[counter++] = p;
			if (counter >= result.size())
				break;
		}
	}

	void plotMatsubara(PlotDataType& result,
	    const PlotParamsType& params) const
	{
		SizeType counter = 0;
		SizeType n = params.numberOfMatsubaras;
		if (result.size() == 0)
			result.resize(n);
		for (SizeType omegaIndex = 0;
		     omegaIndex < params.numberOfMatsubaras;
		     ++omegaIndex) {
			ComplexType z(params.delta,
			    matsubara(omegaIndex, params));
			ComplexType res = iOfOmega(z, Eg_, isign_);
			std::pair p(PsimagLite::imag(z),
			    res);
			result[counter++] = p;
			if (counter >= result.size())
				break;
		}
	}
	//! Cases:
	//! (1) < phi0|A (z+(E0-e_k))^{-1}|A^\dagger|phi0> and
	//! (2) < phi0|A^\dagger (z-(E0-e_k))^{-1}|A|phi0>
	//! (There are actually 4 cases for the off-diagonal gf because
	//! A has two cases:
	//! (1) A = c_i + c_j and
	//! (2) A = c_i - c_j
	ComplexType iOfOmega(const ComplexType& z, RealType offset, int isign) const

	{
		if (PsimagLite::real(weight_) == 0 && PsimagLite::imag(weight_) == 0)
			return ComplexType(0, 0);

		ComplexType sum = 0;
		for (SizeType l = 0; l < intensity_.size(); l++)
			sum += intensity_[l] / (z - isign * (offset - eigs_[l]));

		return sum * weight_;
	}

	SizeType size() const { return ab_.size(); }

	FreqEnum freqType() const { return freqEnum_; }

private:

	void diagonalize()
	{
		if (PsimagLite::real(weight_) == 0 && PsimagLite::imag(weight_) == 0)
			return;

		MatrixType T;
		ab_.buildDenseMatrix(T);
		eigs_.resize(T.rows());
		diag(T, eigs_, 'V');
		intensity_.resize(T.rows());
		for (SizeType i = 0; i < T.rows(); i++) {
			intensity_[i] = T(0, i) * T(0, i);
		}
	}

	RealType matsubara(int ind, const PlotParamsType& params) const
	{
		return (2.0 * ind + 1.0) * M_PI / params.beta;
	}

	ProgressIndicator progress_;
	FreqEnum freqEnum_;
	TridiagonalMatrixType ab_;
	RealType Eg_;
	std::complex weight_;
	int isign_;
	typename Vector::Type eigs_;
	typename Vector::Type intensity_;
}; // class ContinuedFraction
} // namespace PsimagLite
/*@}*/
#endif // CONTINUED_FRACTION_H
PsimagLite-3.06/src/ContinuedFractionCollection.h000066400000000000000000000074111446452427400221110ustar00rootroot00000000000000
/*
// BEGIN LICENSE BLOCK
Copyright (c) 2009 , UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************

*/
/** \ingroup DMRG */
/*@{*/

/*! \file ContinuedFractionCollection.h
 *
 * We need many cont. fractions for the Green's function
 * on different sites, because, you know, we need
 * c_i + c_j and also c_i - c_j, and so on.
 * This class handles the composition
 */

#ifndef CONTINUED_FRACTION_COLL_H
#define CONTINUED_FRACTION_COLL_H
#include "FreqEnum.h"
#include "ProgressIndicator.h"
#include "TypeToString.h"
#include 

namespace PsimagLite
{

template 
class ContinuedFractionCollection
{
public:

	typedef ContinuedFractionType_ ContinuedFractionType;
	typedef typename ContinuedFractionType::ComplexType ComplexType;
	typedef typename ContinuedFractionType::TridiagonalMatrixType
	    TridiagonalMatrixType;
	typedef typename TridiagonalMatrixType::value_type RealType;
	typedef typename ContinuedFractionType::MatrixType MatrixType;
	typedef typename ContinuedFractionType::PlotDataType PlotDataType;
	typedef typename ContinuedFractionType::PlotParamsType PlotParamsType;

	ContinuedFractionCollection(FreqEnum freqEnum)
	    : freqEnum_(freqEnum)
	    , progress_("ContinuedFractionCollection")
	{
	}

	template 
	ContinuedFractionCollection(IoInputType& io, SizeType level = 0)
	    : freqEnum_(FREQ_REAL)
	    , progress_("ContinuedFractionCollection")
	{
		int n = 0;
		io.readline(n, "#CONTINUEDFRACTIONCOLLECTION=", level);
		if (n <= 0) {
			String s = "ContinuedFractionCollection::ctor(...): ";
			s += "Expected a positive number of items, got " + ttos(n);
			throw RuntimeError(s.c_str());
		}
		for (SizeType i = 0; i < SizeType(n); i++) {
			ContinuedFractionType cf(io);
			data_.push_back(cf);
			freqEnum_ = cf.freqType();
		}
	}

	template 
	void write(IoOutputType& io) const
	{
		io.write(data_.size(), "#CONTINUEDFRACTIONCOLLECTION");
		for (SizeType i = 0; i < data_.size(); i++)
			data_[i].write(io, "");
	}

	void push(const ContinuedFractionType& cf) { data_.push_back(cf); }

	void plot(PlotDataType& result, const PlotParamsType& params) const
	{
		for (SizeType i = 0; i < data_.size(); i++) {
			PlotDataType result1;
			data_[i].plot(result1, params);
			accumulate(result, result1);
		}
	}

	void plotOne(SizeType i, PlotDataType& result, const PlotParamsType& params) const
	{
		data_[i].plot(result, params);
	}

	SizeType size() const { return data_.size(); }

	FreqEnum freqType() const { return freqEnum_; }

private:

	void accumulate(PlotDataType& v1, const PlotDataType& v2) const
	{
		bool wasEmpty = false;
		if (v1.size() == 0) {
			wasEmpty = true;
			v1.resize(v2.size());
		} else {
			if (v1.size() != v2.size()) {
				String s = "ContinuedFractionCollection::acc...(...)";
				s += " vectors must be of same length\n";
				throw RuntimeError(s.c_str());
			}
		}
		for (SizeType i = 0; i < v1.size(); i++) {

			if (wasEmpty) {
				v1[i].first = v2[i].first;
				v1[i].second = v2[i].second;
			} else {
				if (v1[i].first != v2[i].first)
					throw RuntimeError(
					    "CF: x coordinate different\n");
				v1[i].second += v2[i].second;
			}
		}
	}

	FreqEnum freqEnum_;
	ProgressIndicator progress_;
	typename Vector::Type data_;
}; // class ContinuedFractionCollection
} // namespace PsimagLite
/*@}*/
#endif // CONTINUED_FRACTION_COLL_H
PsimagLite-3.06/src/CrsMatrix.h000066400000000000000000001206341446452427400163760ustar00rootroot00000000000000/*
Copyright (c) 2009-2012-2018, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 2.]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup DMRG */
/*@{*/

/*! \file CrsMatrix.h
 *
 *  A class to represent a sparse matrix in Compressed Row Storage
 *
 */

#ifndef CRSMATRIX_HEADER_H
#define CRSMATRIX_HEADER_H
#include "BLAS.h"
#include "Complex.h"
#include "Io/IoSerializerStub.h"
#include "Matrix.h"
#include "Mpi.h"
#include "Sort.h"
#include "loki/TypeTraits.h"
#include 
#include 
#include 

namespace PsimagLite
{

//! A Sparse Matrix in Compressed Row Storage (CRS) format.
/**
	The CRS format puts the subsequent nonzero elements of the matrix rows
	in contiguous memory locations. We create 3 vectors: one for complex
   numbers containing the values of the matrix entries and the other two for
   integers ($colind$ and $rowptr$). The vector $values$ stores the values of
   the non-zero elements of the matrix, as they are traversed in a row-wise
   fashion. The $colind$ vector stores the column indices of the elements of the
   $values$ vector. That is, if $values[k] = a[i][j]$ then $colind[k] = j$. The
   $rowptr$ vector stores the locations in the $values$ vector that start a row,
   that is $values[k] = a[i][j]$ if $rowptr[i] \le i < rowptr[i + 1]$. By
   convention, we define $rowptr[N_{dim}]$ to be equal to the number of non-zero
   elements, $n_z$, in the matrix. The storage savings of this approach are
   significant because instead of
	storing $N_{dim}^2$ elements, we need only $2n_z + N_{dim} + 1$ storage
   locations.\\ To illustrate how the CRS format works, consider the
   non-symmetric matrix defined by \begin{equation}
		A=\left[\begin{tabular}{llllll}

		10 &  0 & 0 & 0  & -2 & 0 \\
		3 &  9 &  0 &  0 &  0 &  3 \\
		0 &  7 &  8 &  7 &  0 &  0 \\
		3 &  0 &  8 &  7  & 5 &  0 \\
		0 &   8 &  0 &  9 &  9 & 13 \\
		0 &  4 &  0 &  0 &  2&  -1 \\
	\end{tabular}\right]\end{equation}
	The CRS format for this matrix is then specified by the arrays:\\
	\begin{tt}
		values = [10 -2  3  9  3  7  8  7  3 ... 9 13  4  2 -1 ]\\
		colind = [ 0  4  0  1  5  1  2  3  0 ... 4  5  1  4  5 ]\\
		rowptr = [ 0  2  5  8 12 16 19 ]\\
	\end{tt}
	*/
template 
class CrsMatrix
{

public:

	typedef T MatrixElementType;
	typedef T value_type;

	CrsMatrix()
	    : nrow_(0)
	    , ncol_(0)
	{
	}

	~CrsMatrix() { }

	CrsMatrix(SizeType nrow, SizeType ncol)
	    : nrow_(nrow)
	    , ncol_(ncol)
	{
		resize(nrow, ncol);
	}

	CrsMatrix(SizeType nrow, SizeType ncol, SizeType nonzero)
	    : nrow_(nrow)
	    , ncol_(ncol)
	{
		resize(nrow, ncol, nonzero);
	}

	template 
	CrsMatrix(const CrsMatrix& a)
	{
		colind_ = a.colind_;
		rowptr_ = a.rowptr_;
		values_ = a.values_;
		nrow_ = a.nrow_;
		ncol_ = a.ncol_;
	}

	template 
	CrsMatrix(const CrsMatrix>& a)
	{
		colind_ = a.colind_;
		rowptr_ = a.rowptr_;
		values_ = a.values_;
		nrow_ = a.nrow_;
		ncol_ = a.ncol_;
	}

	explicit CrsMatrix(const Matrix& a)
	{
		int counter = 0;
		double eps = 0;

		resize(a.rows(), a.cols());

		for (SizeType i = 0; i < a.rows(); i++) {
			setRow(i, counter);
			for (SizeType j = 0; j < a.cols(); j++) {
				if (PsimagLite::norm(a(i, j)) <= eps)
					continue;
				pushValue(a(i, j));
				pushCol(j);
				++counter;
			}
		}

		setRow(a.rows(), counter);
	}

	CrsMatrix(SizeType rank, // square matrix ONLY for now
	    const Vector::Type& rows2,
	    const Vector::Type& cols,
	    const typename Vector::Type& vals)
	    : rowptr_(rank + 1)
	    , nrow_(rank)
	    , ncol_(rank)
	{
		Sort::Type> s;
		Vector::Type iperm(rows2.size());
		Vector::Type rows = rows2;
		s.sort(rows, iperm);
		SizeType counter = 0;
		SizeType prevRow = rows[0] + 1;
		for (SizeType i = 0; i < rows.size(); i++) {
			SizeType row = rows[i];
			if (prevRow != row) {
				// add new row
				rowptr_[row] = counter++;
				prevRow = row;
			}

			colind_.push_back(cols[iperm[i]]);
			values_.push_back(vals[iperm[i]]);
		}

		SizeType lastNonZeroRow = rows[rows.size() - 1];
		for (SizeType i = lastNonZeroRow + 1; i <= rank; ++i)
			rowptr_[i] = counter;
	}

	// start closure ctors

	CrsMatrix(const std::ClosureOperator<
	    CrsMatrix,
	    CrsMatrix,
	    std::ClosureOperations::OP_MULT>& c)
	{
		CrsMatrix& x = *this;
		const CrsMatrix& y = c.r1;
		const CrsMatrix& z = c.r2;
		multiply(x, y, z);
	}

	CrsMatrix(const std::ClosureOperator<
	    T,
	    CrsMatrix,
	    std::ClosureOperations::OP_MULT>& c)
	{
		*this = c.r2;
		this->values_ *= c.r1;
	}

	// end all ctors

	template 
	SizeType memResolv(SomeMemResolvType& mres, SizeType, String msg = "") const
	{
		String str = msg;
		str += "CrsMatrix";

		const char* start = reinterpret_cast(this);
		const char* end = reinterpret_cast(&colind_);
		SizeType total = mres.memResolv(&rowptr_, end - start, str + " rowptr");

		start = end;
		end = reinterpret_cast(&values_);
		total += mres.memResolv(&colind_, end - start, str + " colind");

		start = end;
		end = reinterpret_cast(&nrow_);
		total += mres.memResolv(&values_, end - start, str + " values");

		start = end;
		end = reinterpret_cast(&ncol_);
		total += mres.memResolv(&nrow_, end - start, str + " nrow");

		total += mres.memResolv(&ncol_, sizeof(*this) - total, str + " ncol");

		return total;
	}

	void resize(SizeType nrow, SizeType ncol)
	{
		colind_.clear();
		values_.clear();
		rowptr_.clear();
		rowptr_.resize(nrow + 1);
		nrow_ = nrow;
		ncol_ = ncol;
	}

	void clear()
	{
		colind_.clear();
		values_.clear();
		rowptr_.clear();
		nrow_ = ncol_ = 0;
	}

	void resize(SizeType nrow, SizeType ncol, SizeType nonzero)
	{
		nrow_ = nrow;
		ncol_ = ncol;

		// ------------------------------------
		// Note arrays are not cleared out
		// arrays should retain original values
		// ------------------------------------
		rowptr_.resize(nrow_ + 1);
		colind_.resize(nonzero);
		values_.resize(nonzero);
	}

	void reserve(SizeType nonzero)
	{
		// -------------------------------------------------
		// increase internal capacity
		// to avoid repeated allocation expansion and copies
		// -------------------------------------------------
		colind_.reserve(nonzero);
		values_.reserve(nonzero);
	}

	void setRow(SizeType n, SizeType v)
	{
		assert(n < rowptr_.size());
		rowptr_[n] = v;
	}

	void setCol(int n, int v) { colind_[n] = v; }

	void setCol_check(int n, int v)
	{
		if (((size_t)n) == (colind_.size() + 1)) {
			colind_.push_back(v);
		} else {
			colind_[n] = v;
		};
	}

	void setValues(int n, const T& v) { values_[n] = v; }

	void setValues_check(int n, const T& v)
	{
		if (((size_t)n) == (values_.size() + 1)) {
			values_.push_back(v);
		} else {
			values_[n] = v;
		};
	}

	void operator*=(T x) { values_ *= x; }

	bool operator==(const CrsMatrix& op) const
	{
		return (nrow_ == op.nrow_ && ncol_ == op.ncol_ && rowptr_ == op.rowptr_ && colind_ == op.colind_ && values_ == op.values_);
	}

	template 
	typename EnableIf::True,
	    void>::Type
	operator=(const VerySparseMatrixType& m)
	{
		if (!m.sorted())
			throw RuntimeError(
			    "CrsMatrix: VerySparseMatrix must be sorted\n");

		clear();
		SizeType nonZeros = m.nonZeros();
		resize(m.rows(), m.cols(), nonZeros);

		SizeType counter = 0;
		for (SizeType i = 0; i < m.rows(); ++i) {
			setRow(i, counter);

			while (counter < nonZeros && m.getRow(counter) == i) {
				colind_[counter] = m.getColumn(counter);
				values_[counter] = m.getValue(counter);
				counter++;
			}
		}

		setRow(m.rows(), counter);
		checkValidity();
	}

	void operator+=(const CrsMatrix& m)
	{
		CrsMatrix c;
		static const typename Real::Type f1 = 1.0;
		add(c, m, f1);
		*this = c;
	}

	SizeType nonZeros() const
	{
		if (nrow_ >= 1) {
			assert(rowptr_.size() == 1 + nrow_);

			assert(static_cast(rowptr_[nrow_]) == colind_.size());
			assert(static_cast(rowptr_[nrow_]) == values_.size());

			return colind_.size();
		} else {
			return 0;
		};
	}

	/** performs x = x + A * y
	 ** where x and y are vectors and A is a sparse matrix in
	 ** row-compressed format */
	template 
	void matrixVectorProduct(VectorLikeType& x,
	    const VectorLikeType& y) const
	{
		assert(x.size() == y.size());
		for (SizeType i = 0; i < y.size(); i++) {
			assert(i + 1 < rowptr_.size());
			for (int j = rowptr_[i]; j < rowptr_[i + 1]; j++) {
				assert(SizeType(j) < values_.size());
				assert(SizeType(j) < colind_.size());
				assert(SizeType(colind_[j]) < y.size());
				x[i] += values_[j] * y[colind_[j]];
			}
		}
	}

#ifndef NO_DEPRECATED_ALLOWED
	int nonZero() const
	{
		return colind_.size();
	} // DEPRECATED, use nonZeros()
#endif

	SizeType rows() const
	{
		return nrow_;
	}

	SizeType cols() const { return ncol_; }

	void swap(CrsMatrix& other)
	{
		this->rowptr_.swap(other.rowptr_);
		this->colind_.swap(other.colind_);
		this->values_.swap(other.values_);
		SizeType nrow = this->nrow_;
		this->nrow_ = other.nrow_;
		other.nrow_ = nrow;
		SizeType ncol = this->ncol_;
		this->ncol_ = other.ncol_;
		other.ncol_ = ncol;
	}

	void pushCol(SizeType i) { colind_.push_back(i); }

	void pushValue(T const& value) { values_.push_back(value); }

	//! Make a diagonal CRS matrix with value "value"
	void makeDiagonal(SizeType row, T const& value = 0)
	{
		nrow_ = row;
		ncol_ = row;
		rowptr_.resize(row + 1);
		values_.resize(row);
		colind_.resize(row);

		for (SizeType i = 0; i < row; i++) {
			values_[i] = value;
			colind_[i] = i;
			rowptr_[i] = i;
		}

		rowptr_[row] = row;
	}

	const int& getRowPtr(SizeType i) const
	{
		assert(i < rowptr_.size());
		return rowptr_[i];
	}

	const int& getCol(SizeType i) const
	{
		assert(i < colind_.size());
		return colind_[i];
	}

	const T& getValue(SizeType i) const
	{
		assert(i < values_.size());
		return values_[i];
	}

	void conjugate()
	{
		SizeType n = values_.size();
		for (SizeType i = 0; i < n; ++i)
			values_[i] = PsimagLite::conj(values_[i]);
	}

	Matrix toDense() const
	{
		Matrix m;
		crsMatrixToFullMatrix(m, *this);
		return m;
	}

	void checkValidity() const
	{
#ifndef NDEBUG
		SizeType n = nrow_;
		assert(n + 1 == rowptr_.size());
		assert(static_cast(rowptr_[nrow_]) == colind_.size());
		assert(values_.size() == colind_.size());
		assert(nrow_ > 0 && ncol_ > 0);
		typename Vector::Type p(ncol_, 0);
		for (SizeType i = 0; i < n; i++) {
			assert(rowptr_[i] <= rowptr_[i + 1]);
			for (int k = rowptr_[i]; k < rowptr_[i + 1]; k++) {
				SizeType col = colind_[k];
				assert(col < p.size());
				assert(p[col] == 0);
				p[col] = 1;
			}

			for (int k = rowptr_[i]; k < rowptr_[i + 1]; k++)
				p[colind_[k]] = 0;
		}
#endif
	}

	// closures operators start

	template 
	typename EnableIf::isArith || IsComplexNumber::True,
	    CrsMatrix>::Type
	operator=(const std::ClosureOperator<
	    T1,
	    CrsMatrix,
	    std::ClosureOperations::OP_MULT>& c)
	{
		*this = c.r2;
		this->values_ *= c.r1;
		return *this;
	}

	template 
	typename EnableIf::isArith || IsComplexNumber::True,
	    CrsMatrix>::Type
	operator+=(const std::ClosureOperator<
	    T1,
	    CrsMatrix,
	    std::ClosureOperations::OP_MULT>& c)
	{
		CrsMatrix s;
		add(s, c.r2, c.r1);
		this->swap(s);
		return *this;
	}

	template 
	typename EnableIf::isArith || IsComplexNumber::True,
	    CrsMatrix>::Type
	operator+=(const std::ClosureOperator<
	    std::ClosureOperator,
	    CrsMatrix,
	    std::ClosureOperations::OP_MULT>& c)
	{
		CrsMatrix s;
		multiply(s, c.r1.r2, c.r2);
		CrsMatrix s2;
		add(s2, s, c.r1.r1);
		this->swap(s2);
		return *this;
	}

	// closures operators end

	void send(int root, int tag, MPI::CommType mpiComm)
	{
		MPI::send(nrow_, root, tag, mpiComm);
		MPI::send(ncol_, root, tag + 1, mpiComm);
		MPI::send(rowptr_, root, tag + 2, mpiComm);
		MPI::send(colind_, root, tag + 3, mpiComm);
		MPI::send(values_, root, tag + 4, mpiComm);
	}

	void recv(int root, int tag, MPI::CommType mpiComm)
	{
		MPI::recv(nrow_, root, tag, mpiComm);
		MPI::recv(ncol_, root, tag + 1, mpiComm);
		MPI::recv(rowptr_, root, tag + 2, mpiComm);
		MPI::recv(colind_, root, tag + 3, mpiComm);
		MPI::recv(values_, root, tag + 4, mpiComm);
	}

	void
	write(String label, IoSerializer& ioSerializer, IoSerializer::WriteMode mode = IoSerializer::NO_OVERWRITE) const
	{
		if (nrow_ > 0)
			checkValidity();
		if (mode != IoSerializer::ALLOW_OVERWRITE)
			ioSerializer.createGroup(label);
		ioSerializer.write(label + "/nrow_", nrow_, mode);
		ioSerializer.write(label + "/ncol_", ncol_, mode);
		if (nrow_ == 0 || ncol_ == 0)
			return;
		ioSerializer.write(label + "/rowptr_", rowptr_, mode);
		assert(rowptr_.size() == nrow_ + 1);
		if (rowptr_[nrow_] == 0)
			return;
		ioSerializer.write(label + "/colind_", colind_, mode);
		ioSerializer.write(label + "/values_", values_, mode);
	}

	void overwrite(String label, IoSerializer& ioSerializer) const
	{
		write(label, ioSerializer, IoSerializer::ALLOW_OVERWRITE);
	}
	void read(String label, IoSerializer& ioSerializer)
	{
		ioSerializer.read(nrow_, label + "/nrow_");
		ioSerializer.read(ncol_, label + "/ncol_");
		if (nrow_ == 0 || ncol_ == 0)
			return;
		ioSerializer.read(rowptr_, label + "/rowptr_");
		assert(rowptr_.size() == nrow_ + 1);
		if (rowptr_[nrow_] == 0)
			return;
		ioSerializer.read(colind_, label + "/colind_");
		ioSerializer.read(values_, label + "/values_");
		checkValidity();
	}

	template 
	friend bool isZero(const CrsMatrix&, double);

	template 
	friend typename Real::Type norm2(const CrsMatrix& m);

	template 
	friend std::ostream& operator<<(std::ostream& os,
	    const CrsMatrix& m);

	template 
	friend void difference(const CrsMatrix& A, const CrsMatrix& B);

	template 
	friend void MpiBroadcast(CrsMatrix* v, int rank);

	template 
	friend void MpiSend(CrsMatrix* v, int iproc, int i);

	template 
	friend void MpiRecv(CrsMatrix* v, int iproc, int i);

	template 
	friend std::istream& operator>>(std::istream& is,
	    CrsMatrix& m);

	template 
	friend void bcast(CrsMatrix& m);

private:

	template 
	typename std::enable_if<
	    std::is_same::Type>::value || std::is_same::value,
	    void>::type
	add(CrsMatrix& c, const CrsMatrix& m, const T1& t1) const
	{
		assert(m.rows() == m.cols());
		const T1 one = 1.0;
		if (nrow_ >= m.rows())
			operatorPlus(c, *this, one, m, t1);
		else
			operatorPlus(c, m, t1, *this, one);
	}

	typename Vector::Type rowptr_;
	typename Vector::Type colind_;
	typename Vector::Type values_;
	SizeType nrow_;
	SizeType ncol_;
}; // class CrsMatrix

// Companion functions below:

template 
std::ostream& operator<<(std::ostream& os, const CrsMatrix& m)
{
	SizeType n = m.rows();
	if (n == 0) {
		os << "0 0\n";
		return os;
	}

	os << n << " " << m.cols() << "\n";
	for (SizeType i = 0; i < n + 1; i++)
		os << m.rowptr_[i] << " ";
	os << "\n";

	SizeType nonzero = m.nonZeros();
	os << nonzero << "\n";
	for (SizeType i = 0; i < nonzero; i++)
		os << m.colind_[i] << " ";
	os << "\n";

	os << nonzero << "\n";
	for (SizeType i = 0; i < nonzero; i++)
		os << m.values_[i] << " ";
	os << "\n";

	return os;
}

template 
std::istream& operator>>(std::istream& is, CrsMatrix& m)
{
	int n;
	is >> n;
	if (n < 0)
		throw RuntimeError(
		    "is>>CrsMatrix(...): Rows must be positive\n");

	int ncol = 0;
	if (ncol < 0)
		throw RuntimeError(
		    "is>>CrsMatrix(...): Cols must be positive\n");
	is >> ncol;

	if (n == 0 || ncol == 0)
		return is;

	m.resize(n, ncol);
	for (SizeType i = 0; i < m.rowptr_.size(); i++)
		is >> m.rowptr_[i];

	SizeType nonzero;
	is >> nonzero;
	m.colind_.resize(nonzero);
	for (SizeType i = 0; i < m.colind_.size(); i++)
		is >> m.colind_[i];

	is >> nonzero;
	m.values_.resize(nonzero);
	for (SizeType i = 0; i < m.values_.size(); i++)
		is >> m.values_[i];

	return is;
}

template 
class IsMatrixLike>
{
public:

	enum { True = true };
};

template 
void bcast(CrsMatrix& m)
{
	MPI::bcast(m.rowptr_);
	MPI::bcast(m.colind_);
	MPI::bcast(m.values_);
	MPI::bcast(m.nrow_);
	MPI::bcast(m.ncol_);
}

//! Transforms a Compressed-Row-Storage (CRS) into a full Matrix (Fast version)
template 
void crsMatrixToFullMatrix(Matrix& m, const CrsMatrix& crsMatrix)
{
	m.resize(crsMatrix.rows(), crsMatrix.cols(), 0);
	for (SizeType i = 0; i < crsMatrix.rows(); i++) {
		//  for (SizeType k=0;k
void fullMatrixToCrsMatrix(CrsMatrix& crsMatrix, const Matrix& a)
{
	const T zval = 0.0;
	SizeType rows = a.rows();
	SizeType cols = a.cols();
	SizeType nonZeros = rows * cols;

	const bool use_push = true;

	if (use_push) {
		// ------------------------------
		// avoid filling array with zeros
		// ------------------------------
		crsMatrix.resize(rows, cols);
		crsMatrix.reserve(nonZeros);
	} else {
		crsMatrix.resize(rows, cols, nonZeros);
	};

	SizeType counter = 0;
	for (SizeType i = 0; i < rows; ++i) {
		crsMatrix.setRow(i, counter);
		for (SizeType j = 0; j < cols; ++j) {
			const T& val = a(i, j);
			if (val == zval)
				continue;

			if (use_push) {
				crsMatrix.pushValue(val);
				crsMatrix.pushCol(j);
			} else {
				crsMatrix.setValues(counter, val);
				crsMatrix.setCol(counter, j);
			};
			++counter;
		}
	}

	crsMatrix.setRow(rows, counter);
	crsMatrix.checkValidity();
}

/** If order==false then
		creates B such that
   B_{i1+j1*nout,i2+j2*nout)=A(j1,j2)\delta_{i1,i2} if order==true then creates
   B such that B_{i1+j1*na,i2+j2*na)=A(i1,i2)\delta_{j1,j2} where na=rank(A)
	  */

template 
typename EnableIf<
    IsVectorLike::True && Loki::TypeTraits::isFloat,
    void>::Type
externalProduct(CrsMatrix& B, const CrsMatrix& A, SizeType nout, const VectorLikeType& signs, bool order, const PsimagLite::Vector::Type& permutationFull)
{
	if (A.rows() > 0)
		A.checkValidity();
	// -------------------------------------
	//  B = kron(eye, A)   if (is_A_fastest)
	//  B = kron(A, eye)   otherwise
	// -------------------------------------
	SizeType nrow_A = A.rows();
	SizeType ncol_A = A.cols();
	SizeType n = nout;
	SizeType nrow_eye = n;
	SizeType ncol_eye = n;
	SizeType nnz_A = A.nonZeros();

	SizeType nrow_B = n * nrow_A;
	SizeType ncol_B = n * ncol_A;
	SizeType nnz_B = n * nnz_A;

	B.resize(nrow_B, ncol_B, nnz_B);

	bool is_A_fastest = order;

	if (nrow_A != ncol_A)
		throw RuntimeError(
		    "externalProduct: matrices must be square\n");

	// -----------------------
	// setup row pointers in B
	// Note: if (is_A_fastest)  then
	//          B( [ia,ie], [ja,je] ) = A(ia,ja) * eye(ie,je)
	//       else
	//          B( [ie,ia], [je,ja] ) = A(ia,ja) * eye(ie,je)
	//       endif
	//
	//  where [ia,ie] = ia + ie * nrow_A,   [ja,je] = ja + je * ncol_A
	//        [ie,ia] = ie + ia * nrow_eye, [je,ja] = je + ja * ncol_eye
	// -----------------------

	// -------------------------------------------------
	// calculate the number of nonzeros in each row of B
	// -------------------------------------------------
	std::vector nnz_B_row(nrow_B);

	assert(nrow_A * nrow_eye <= permutationFull.size());

	for (SizeType ia = 0; ia < nrow_A; ia++) {

		SizeType nnz_row = A.getRowPtr(ia + 1) - A.getRowPtr(ia);

		for (SizeType ie = 0; ie < nrow_eye; ie++) {
			SizeType ib = (is_A_fastest)
			    ? permutationFull[ia + ie * nrow_A]
			    : permutationFull[ie + ia * nrow_eye];
			nnz_B_row[ib] = nnz_row;
		};
	};

	// -------------------------------
	// setup row pointers in matrix B
	// -------------------------------
	std::vector B_rowptr(nrow_B);

	SizeType ip = 0;
	for (SizeType ib = 0; ib < nrow_B; ib++) {

		B_rowptr[ib] = ip;
		B.setRow(ib, ip);

		ip += nnz_B_row[ib];
	};
	assert(ip == nnz_B);
	B.setRow(nrow_B, nnz_B);

	// ---------------------------
	// copy entries into matrix B
	// ---------------------------

	// ----------------------------------------------
	// single pass over non-zero entries of matrix A
	// ----------------------------------------------
	for (SizeType ia = 0; ia < nrow_A; ia++) {
		for (int k = A.getRowPtr(ia); k < A.getRowPtr(ia + 1); k++) {

			// --------------------
			// entry aij = A(ia,ja)
			// --------------------
			SizeType ja = A.getCol(k);
			T aij = A.getValue(k);

			for (SizeType ie = 0; ie < nrow_eye; ie++) {
				SizeType je = ie;

				SizeType ib = (is_A_fastest)
				    ? ia + ie * nrow_A
				    : ie + ia * nrow_eye;

				SizeType jb = (is_A_fastest)
				    ? ja + je * ncol_A
				    : je + ja * ncol_eye;

				// --------------------
				// entry bij = B(ib,jb)
				// --------------------
				int alpha = ie;
				T bij = (is_A_fastest) ? aij : aij * signs[alpha];

				SizeType ip = B_rowptr[permutationFull[ib]];

				assert(jb < permutationFull.size());
				B.setCol(ip, permutationFull[jb]);
				B.setValues(ip, bij);

				++B_rowptr[permutationFull[ib]];
			};
		};
	};

	if (nrow_B != 0)
		B.checkValidity();
}

//-------

/** If order==false then
		creates C such that C_{i1+j1*nout,i2+j2*nout)=A(j1,j2)B_{i1,i2}
		if order==true then
		creates C such that C_{i1+j1*na,i2+j2*na)=A(i1,i2)B_{j1,j2}
		where na=rank(A) and nout = rank(B)
	  */

template 
typename EnableIf<
    IsVectorLike::True && Loki::TypeTraits::isFloat,
    void>::Type
externalProduct(CrsMatrix& C, const CrsMatrix& A, const CrsMatrix& B, const VectorLikeType& signs, bool order, const PsimagLite::Vector::Type& permutationFull)
{
	const SizeType nfull = permutationFull.size();

	Vector::Type perm(nfull);
	for (SizeType i = 0; i < nfull; ++i)
		perm[permutationFull[i]] = i;

	const SizeType nout = B.rows();
	const SizeType na = A.rows();
	const SizeType noutOrNa = (!order) ? nout : na;
	const CrsMatrix& AorB = (!order) ? A : B;
	const CrsMatrix& BorA = (!order) ? B : A;
	assert(A.rows() == A.cols());
	assert(B.rows() == B.cols());
	assert(nout * na == nfull);
	assert(signs.size() == noutOrNa);
	C.resize(nfull, nfull);
	SizeType counter = 0;
	for (SizeType i = 0; i < nfull; ++i) {
		C.setRow(i, counter);
		const SizeType ind = perm[i];
		div_t q = div(ind, noutOrNa);
		for (int k1 = BorA.getRowPtr(q.rem);
		     k1 < BorA.getRowPtr(q.rem + 1);
		     ++k1) {
			const SizeType col1 = BorA.getCol(k1);
			for (int k2 = AorB.getRowPtr(q.quot);
			     k2 < AorB.getRowPtr(q.quot + 1);
			     ++k2) {
				const SizeType col2 = AorB.getCol(k2);
				SizeType j = permutationFull[col1 + col2 * noutOrNa];
				C.pushCol(j);
				C.pushValue(BorA.getValue(k1) * AorB.getValue(k2) * signs[q.rem]);
				++counter;
			}
		}
	}

	C.setRow(nfull, counter);
	C.checkValidity();
}

template 
void printFullMatrix(const CrsMatrix& s, const String& name, SizeType how = 0, double eps = 1e-20)
{
	Matrix fullm(s.rows(), s.cols());
	crsMatrixToFullMatrix(fullm, s);
	std::cout << "--------->   " << name;
	std::cout << " rank=" << s.rows() << "x" << s.cols()
		  << " <----------\n";
	try {
		if (how == 1)
			mathematicaPrint(std::cout, fullm);
		if (how == 2)
			symbolicPrint(std::cout, fullm);
	} catch (std::exception& e) {
	}

	if (how == 0)
		fullm.print(std::cout, eps);
}

//! C = A*B,  all matrices are CRS matrices
//! idea is from http://web.maths.unsw.edu.au/~farid/Papers/Hons/node23.html
template 
void multiply(CrsMatrix& C, CrsMatrix const& A, CrsMatrix const& B)
{
	int j, s, mlast, itemp, jbk;
	SizeType n = A.rows();
	typename Vector::Type ptr(B.cols(), -1), index(B.cols(), 0);
	typename Vector::Type temp(B.cols(), 0);
	S tmp;

	C.resize(n, B.cols());

	// mlast pointer to the last place we updated in the C vector
	mlast = 0;
	// for (SizeType l=0;l
void multiply(typename Vector::Type& v2, const CrsMatrix& m, const typename Vector::Type& v1)
{
	SizeType n = m.rows();
	v2.resize(n);
	for (SizeType i = 0; i < n; i++) {
		v2[i] = 0;
		for (int j = m.getRowPtr(i); j < m.getRowPtr(i + 1); j++) {
			v2[i] += m.getValue(j) * v1[m.getCol(j)];
		}
	}
}

//! Sets B=transpose(conjugate(A))
template 
void transposeConjugate(CrsMatrix& B, const CrsMatrix& A)
{
	SizeType nrowA = A.rows();
	SizeType ncolA = A.cols();
	SizeType nrowB = ncolA;
	SizeType ncolB = nrowA;

	SizeType nnz_A = A.nonZeros();
	SizeType nnz_B = nnz_A;

	B.resize(nrowB, ncolB, nnz_B);

	std::vector nnz_count(ncolA, 0);

	// ----------------------------------------------------
	// 1st pass to count number of nonzeros per column in A
	// which is equivalent to number of nonzeros
	// per row in B = transpose(conjugate(A))
	// ----------------------------------------------------
	for (SizeType ia = 0; ia < nrowA; ia++) {
		for (int k = A.getRowPtr(ia); k < A.getRowPtr(ia + 1); k++) {
			SizeType ja = A.getCol(k);
			++nnz_count[ja];
		};
	};

	// -----------------------
	// setup row pointers in B
	// -----------------------
	SizeType ipos = 0;
	for (SizeType ib = 0; ib < nrowB; ib++) {
		B.setRow(ib, ipos);
		ipos += nnz_count[ib];
	};
	assert(ipos == nnz_B);
	B.setRow(nrowB, nnz_B);

	// -------------------------------
	// setup row pointers in B matrix
	// -------------------------------
	std::vector B_rowptr(nrowB);
	for (SizeType ib = 0; ib < nrowB; ib++) {
		B_rowptr[ib] = B.getRowPtr(ib);
	};

	// -------------------------------------------
	// 2nd pass over matrix A to assign values to B
	// -------------------------------------------
	for (SizeType ia = 0; ia < nrowA; ia++) {
		for (int k = A.getRowPtr(ia); k < A.getRowPtr(ia + 1); k++) {

			SizeType ja = A.getCol(k);
			S2 aij = A.getValue(k);

			// ---------------------------------
			// B(ib=ja,jb=ia) = conj( A(ia,ja) )
			// ---------------------------------
			SizeType ib = ja;
			SizeType jb = ia;

			SizeType ip = B_rowptr[ib];

			// B.colind_[ ip ] = jb;
			// B.values_[ ip ] = PsimagLite::conj( aij );

			B.setCol(ip, jb);
			B.setValues(ip, PsimagLite::conj(aij));

			++B_rowptr[ib];
		};
	};
}

//! Sets A=B*b1+C*c1, restriction: B.size has to be larger or equal than C.size
template 
void operatorPlus(CrsMatrix& A, const CrsMatrix& B, T1& b1, const CrsMatrix& C, T1& c1)
{
	const T zero = static_cast(0.0);

	SizeType nrow_B = B.rows();
	SizeType ncol_B = B.cols();
	SizeType nrow_C = C.rows();
	SizeType ncol_C = C.cols();

	// ------------------------------
	// nrow_A = MAX( nrow_B, nrow_C )
	// ncol_A = MAX( ncol_B, ncol_C )
	// ------------------------------
	SizeType nrow_A = (nrow_B >= nrow_C) ? nrow_B : nrow_C;
	SizeType ncol_A = (ncol_B >= ncol_C) ? ncol_B : ncol_C;

	A.resize(nrow_A, ncol_A);

	// ------------------------------------------------------
	// TODO: using A.resize(nrow_A,ncol_A,nnz_A) may not work correctly
	// ------------------------------------------------------
	const bool set_nonzeros = true;
	if (set_nonzeros) {
		SizeType nnz_B = B.nonZeros();
		SizeType nnz_C = C.nonZeros();

		// -----------------------------------------------
		// worst case when no overlap in sparsity pattern
		// between matrix B and matrix C
		// -----------------------------------------------
		SizeType nnz_A = nnz_B + nnz_C;

		A.reserve(nnz_A);
	};

	// ------------------------------------------
	// temporary vectors to accelerate processing
	// ------------------------------------------
	std::vector valueTmp(ncol_A, zero);
	std::vector is_examined_already(ncol_A, false);

	SizeType counter = 0;
	for (SizeType irow = 0; irow < nrow_A; irow++) {
		A.setRow(irow, counter);

		const bool is_valid_B_row = (irow < nrow_B);
		const bool is_valid_C_row = (irow < nrow_C);

		const int kstart_B = (is_valid_B_row) ? B.getRowPtr(irow) : 0;
		const int kend_B = (is_valid_B_row) ? B.getRowPtr(irow + 1) : 0;

		const int kstart_C = (is_valid_C_row) ? C.getRowPtr(irow) : 0;
		const int kend_C = (is_valid_C_row) ? C.getRowPtr(irow + 1) : 0;

		// --------------------------------
		// check whether there is work to do
		// --------------------------------
		const bool has_work = ((kend_B - kstart_B) + (kend_C - kstart_C) >= 1);
		if (!has_work)
			continue;

		// -------------------------------
		// add contributions from matrix B and matrix C
		// -------------------------------
		for (int k = kstart_B; k < kend_B; k++) {
			const T bij = B.getValue(k);
			const SizeType jcol = B.getCol(k);

			assert(jcol < ncol_A);

			valueTmp[jcol] += (bij * b1);
		};

		for (int k = kstart_C; k < kend_C; k++) {
			const T cij = C.getValue(k);
			const SizeType jcol = C.getCol(k);

			assert(jcol < ncol_A);

			valueTmp[jcol] += (cij * c1);
		};

		// --------------------
		// copy row to matrix A
		// --------------------

		for (int k = kstart_B; k < kend_B; k++) {
			const SizeType jcol = B.getCol(k);
			if (!is_examined_already[jcol]) {
				is_examined_already[jcol] = true;

				const T aij = valueTmp[jcol];
				const bool is_zero = (aij == zero);
				if (!is_zero) {
					A.pushCol(jcol);
					A.pushValue(aij);
					counter++;
				};
			};
		};

		for (int k = kstart_C; k < kend_C; k++) {
			const SizeType jcol = C.getCol(k);
			if (!is_examined_already[jcol]) {
				is_examined_already[jcol] = true;

				const T aij = valueTmp[jcol];
				const bool is_zero = (aij == zero);
				if (!is_zero) {
					A.pushCol(jcol);
					A.pushValue(aij);
					counter++;
				};
			};
		};

		// --------------------------------------------------
		// reset vectors valueTmp[] and is_examined_already[]
		// --------------------------------------------------

		for (int k = kstart_B; k < kend_B; k++) {
			const SizeType jcol = B.getCol(k);
			valueTmp[jcol] = zero;
			is_examined_already[jcol] = false;
		};

		for (int k = kstart_C; k < kend_C; k++) {
			const SizeType jcol = C.getCol(k);
			valueTmp[jcol] = zero;
			is_examined_already[jcol] = false;
		};

	}; // end for irow

	A.setRow(nrow_A, counter);

	// ----------------------------------------
	// set exact number of nonzeros in matrix A
	// ----------------------------------------
	SizeType nnz_A = counter;
	A.resize(nrow_A, ncol_A, nnz_A);

	A.checkValidity();
}

//! Sets A=B0*b0+B1*b1 + ...
template 
void sum(CrsMatrix& A, const std::vector*>& Bmats, const std::vector& bvec)
{
	SizeType Bmats_size = Bmats.size();

	// ------------------------------
	// nrow_A = MAX( nrow_B(:) )
	// ncol_A = MAX( ncol_B(:) )
	// ------------------------------
	SizeType nrow_A = 0;
	SizeType ncol_A = 0;
	SizeType nnz_sum = 0;
	SizeType nnz_max = 0;

	for (SizeType imat = 0; imat < Bmats_size; ++imat) {
		assert(imat < Bmats.size());
		const CrsMatrix& thisMat = *(Bmats[imat]);
		SizeType nrow_B = thisMat.rows();
		SizeType ncol_B = thisMat.cols();
		SizeType nnz_B = thisMat.nonZeros();

		nrow_A = (nrow_B > nrow_A) ? nrow_B : nrow_A;
		ncol_A = (ncol_B > ncol_A) ? ncol_B : ncol_A;

		nnz_max = (nnz_B > nnz_max) ? nnz_B : nnz_max;
		nnz_sum += nnz_B;
	}

	A.resize(nrow_A, ncol_A);

	// ---------------------------------------------------
	// lower bound for total number of nonzeros is nnz_max
	// upper bound for total number of nonzeros is nnz_sum
	// initially set it to 2 * nnz_max
	// ---------------------------------------------------
	A.reserve((2 * nnz_max > nnz_sum) ? nnz_sum : 2 * nnz_max);

	// ------------------------------------------------------
	// TODO: using A.resize(nrow_A,ncol_A,nnz_A) may not work correctly
	// ------------------------------------------------------
	const bool set_nonzeros = true;
	if (set_nonzeros) {
		// -----------------------------------------------
		// worst case when no overlap in sparsity pattern
		// among matrices
		// -----------------------------------------------

		A.reserve(nnz_sum);
	}

	// ------------------------------------------
	// temporary vectors to accelerate processing
	// ------------------------------------------
	std::vector valueTmp(ncol_A);
	std::vector is_examined_already(ncol_A, false);

	std::vector column_index;
	column_index.reserve(ncol_A);

	SizeType counter = 0;
	for (SizeType irow = 0; irow < nrow_A; ++irow) {
		A.setRow(irow, counter);

		column_index.clear();

		for (SizeType imat = 0; imat < Bmats_size; ++imat) {
			assert(imat < Bmats.size());
			const CrsMatrix& thisMat = *(Bmats[imat]);
			const SizeType nrow_B = thisMat.rows();
			const bool is_valid_B_row = (irow < nrow_B);

			const SizeType kstart_B = (is_valid_B_row) ? thisMat.getRowPtr(irow) : 0;
			const SizeType kend_B = (is_valid_B_row) ? thisMat.getRowPtr(irow + 1) : 0;

			// --------------------------------
			// check whether there is work to do
			// --------------------------------
			const bool has_work = ((kend_B - kstart_B) >= 1);
			if (!has_work)
				continue;

			// -------------------------------
			// add contributions from matrix Bmats[i]
			// -------------------------------
			const T1 b1 = bvec[imat];
			for (SizeType k = kstart_B; k < kend_B; ++k) {
				const T bij = thisMat.getValue(k);
				const SizeType jcol = thisMat.getCol(k);

				assert(jcol < ncol_A);

				if (is_examined_already[jcol]) {
					valueTmp[jcol] += (bij * b1);
				} else {
					// ------------------------------------
					// new column entry not examined before
					// ------------------------------------

					is_examined_already[jcol] = true;

					valueTmp[jcol] = (bij * b1);

					column_index.push_back(jcol);
				}
			}
		} // end for imat

		// --------------------------------------
		// copy row to matrix A and reset vectors
		// --------------------------------------

		const SizeType kmax = column_index.size();
		for (SizeType k = 0; k < kmax; ++k) {
			const SizeType jcol = column_index[k];

			A.pushCol(jcol);
			A.pushValue(valueTmp[jcol]);
			is_examined_already[jcol] = false;
		}

		counter += kmax;
	} // end for irow

	SizeType nnz_A = counter;
	A.setRow(nrow_A, nnz_A);

	// ----------------------------------------
	// set exact number of nonzeros in matrix A
	//
	// note: this might be expensive in allocating another copy
	// and copying all the non-zero entries
	// ----------------------------------------
	const bool set_exact_nnz = true;
	if (set_exact_nnz)
		A.resize(nrow_A, ncol_A, nnz_A);

	A.checkValidity();
}

template 
bool isHermitian(const CrsMatrix& A, bool verbose = false)
{
	if (A.rows() != A.cols())
		return false;
	Matrix dense;
	crsMatrixToFullMatrix(dense, A);
	return isHermitian(dense, verbose);
}

template 
bool isAntiHermitian(const CrsMatrix& A)
{
	if (A.rows() != A.cols())
		return false;
	Matrix dense;
	crsMatrixToFullMatrix(dense, A);
	return isAntiHermitian(dense);
}

template 
void fromBlockToFull(CrsMatrix& Bfull, const CrsMatrix& B, SizeType offset)
{
	const bool use_push = true;
	int nrows_Bfull = Bfull.rows();
	int ncols_Bfull = Bfull.cols();
	int nnz_Bfull = B.nonZeros();
	Bfull.clear();

	if (use_push) {
		Bfull.resize(nrows_Bfull, ncols_Bfull);
		Bfull.reserve(nnz_Bfull);
	} else {
		Bfull.resize(nrows_Bfull, ncols_Bfull, nnz_Bfull);
	};

	int counter = 0;
	for (SizeType i = 0; i < offset; ++i)
		Bfull.setRow(i, counter);

	for (SizeType ii = 0; ii < B.rows(); ++ii) {
		SizeType i = ii + offset;
		Bfull.setRow(i, counter);
		for (int jj = B.getRowPtr(ii); jj < B.getRowPtr(ii + 1); ++jj) {
			SizeType j = B.getCol(jj) + offset;
			T tmp = B.getValue(jj);
			if (use_push) {
				Bfull.pushCol(j);
				Bfull.pushValue(tmp);
			} else {
				Bfull.setCol(counter, j);
				Bfull.setValues(counter, tmp);
			};
			counter++;
		}
	}

	for (SizeType i = B.rows() + offset; i < Bfull.rows(); ++i)
		Bfull.setRow(i, counter);

	Bfull.setRow(Bfull.rows(), counter);
	Bfull.checkValidity();
}

template 
bool isDiagonal(const CrsMatrix& A, double eps = 1e-6, bool checkForIdentity = false)
{
	if (A.rows() != A.cols())
		return false;
	SizeType n = A.rows();
	const T f1 = (-1.0);
	for (SizeType i = 0; i < n; i++) {
		for (int k = A.getRowPtr(i); k < A.getRowPtr(i + 1); k++) {
			SizeType col = A.getCol(k);
			const T& val = A.getValue(k);
			if (checkForIdentity && col == i && PsimagLite::norm(val + f1) > eps) {
				return false;
			}
			if (col != i && PsimagLite::norm(val) > eps) {
				return false;
			}
		}
	}
	return true;
}

template 
bool isTheIdentity(const CrsMatrix& A, double eps = 1e-6)
{
	return isDiagonal(A, eps, true);
}

template 
typename Real::Type norm2(const CrsMatrix& m)
{
	T val = 0;
	for (SizeType i = 0; i < m.values_.size(); i++)
		val += PsimagLite::conj(m.values_[i]) * m.values_[i];

	return PsimagLite::real(val);
}

template 
Matrix multiplyTc(const CrsMatrix& a, const CrsMatrix& b)
{

	CrsMatrix bb, c;
	transposeConjugate(bb, b);
	multiply(c, a, bb);
	Matrix cc;
	crsMatrixToFullMatrix(cc, c);
	return cc;
}

template 
bool isZero(const CrsMatrix& A, double eps = 0)
{
	SizeType n = A.values_.size();
	for (SizeType i = 0; i < n; ++i) {
		if (std::abs(A.values_[i]) > eps)
			return false;
	}

	return true;
}

} // namespace PsimagLite
/*@}*/
#endif
PsimagLite-3.06/src/DavidsonSolver.h000066400000000000000000000125031446452427400174170ustar00rootroot00000000000000/*
Copyright (c) 2009-2012, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************


*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file DavidsonSolver.h
 *
 *  A class to represent a generic Davidson Solver
 *  reference: Ernest R. Davidson, J. Comp. Phys. 17, 87-94 (1975).
 *
 *  http://web.eecs.utk.edu/~dongarra/etemplates/node138.html
 */

#ifndef DAVIDSON_SOLVER_H
#define DAVIDSON_SOLVER_H
#include "LanczosOrDavidsonBase.h"
#include "LanczosVectors.h"
#include "Matrix.h"
#include "ProgressIndicator.h"
#include "Random48.h"
#include "TridiagonalMatrix.h"
#include "Vector.h"
#include 

namespace PsimagLite
{

template 
class DavidsonSolver
    : public LanczosOrDavidsonBase
{

	typedef typename SolverParametersType::RealType RealType;
	typedef LanczosOrDavidsonBase
	    BaseType;
	typedef typename VectorType::value_type ComplexOrRealType;
	typedef typename BaseType::VectorRealType VectorRealType;
	typedef typename BaseType::VectorVectorType VectorVectorType;

public:

	DavidsonSolver(MatrixType const& mat,
	    const SolverParametersType& params)
	    : progress_("DavidsonSolver")
	    , mat_(mat)
	    , steps_(params.steps)
	    , eps_(params.tolerance)
	{
		OstringStream msg(std::cout.precision());
		msg() << "Constructing... mat.rank=" << mat_.rows();
		msg() << " steps=" << steps_ << " eps=" << eps_;
		progress_.printline(msg, std::cout);
	}

	void computeOneState(RealType&, VectorType&, const VectorType&, SizeType)
	{
		String s(__FILE__);
		s += " Unimplemented\n";
		throw RuntimeError(s.c_str());
	}

	void computeAllStatesBelow(VectorRealType&, VectorVectorType&, const VectorType&, SizeType)
	{
		String s(__FILE__);
		s += " Unimplemented\n";
		throw RuntimeError(s.c_str());
	}

private:

	void algorithm4_14(VectorType& t,
	    const typename Vector::Type& v)
	{
		SizeType m = v.size();
		if (m == 0)
			return;
		// select a value for k less than 1
		RealType k = 0.25;
		RealType tauin = PsimagLite::real(t * t);
		for (SizeType i = 0; i < m; i++) {
			ComplexOrRealType tmp = scalarProduct(v[i], t);
			t = t - tmp * t;
		}
		if (PsimagLite::real(t * t) / tauin > k)
			return;
		for (SizeType i = 0; i < m; i++) {
			ComplexOrRealType tmp = scalarProduct(v[i], t);
			t = t - tmp * v[i];
		}
	}

	void callMinRes()
	{
		String s(__FILE__);
		s += " Unimplemented\n";
		throw RuntimeError(s.c_str());
	}

	void largestEigenpair(RealType& theta, VectorType& s, const Matrix& M)
	{
		String st(__FILE__);
		st += " Unimplemented\n";
		throw RuntimeError(st.c_str());
	}

	ProgressIndicator progress_;
	const MatrixType& mat_;
	SizeType steps_;
	RealType eps_;
}; // class DavidsonSolver
} // namespace PsimagLite

/*@}*/
#endif // DAVIDSON_SOLVER_H
PsimagLite-3.06/src/DeepCopyOrNot.h000066400000000000000000000015421446452427400171500ustar00rootroot00000000000000#ifndef DEEPCOPYORNOT_H
#define DEEPCOPYORNOT_H
#include "Vector.h"

namespace PsimagLite
{

template  // UnderlyingType must have copy ctor
class DeepCopyOrNot
{

public:

	typedef typename Vector::Type VectorUnderlyingType;

	DeepCopyOrNot(bool isDeep)
	    : isDeep_(isDeep)
	{
	}

	~DeepCopyOrNot()
	{
		SizeType n = garbage_.size();
		for (SizeType i = 0; i < n; ++i) {
			delete garbage_[i];
			garbage_[i] = 0;
		}
	}

	const UnderlyingType& operator()(const UnderlyingType& other)
	{
		if (!isDeep_)
			return other;

		UnderlyingType* tmp = new UnderlyingType(other);
		garbage_.push_back(tmp);
		return *tmp;
	}

private:

	DeepCopyOrNot(const DeepCopyOrNot&);

	DeepCopyOrNot& operator=(const DeepCopyOrNot&);

	bool isDeep_;
	VectorUnderlyingType garbage_;
};
} // namespace PsimagLite
#endif // DEEPCOPYORNOT_H
PsimagLite-3.06/src/Fermi.h000066400000000000000000000065641446452427400155310ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file Fermi.h
 *
 *  Fermi functions and their derivatives
 */

#ifndef FERMI_H_
#define FERMI_H_
#include 

namespace PsimagLite
{

template 
FieldType fermi(const FieldType& x)
{
	if (x > 50)
		return 0;
	if (x < -50)
		return 1;
	if (x < 0)
		return 1.0 / (1.0 + std::exp(x));
	return std::exp(-x) / (1.0 + std::exp(-x));
}

// Derivative (prime) of Fermi's function
template 
FieldType fermiPrime(const FieldType& x)
{
	FieldType res;
	res = -fermi(x) * fermi(-x);
	return res;
}

template 
FieldType logfermi(const FieldType& x)
{
	FieldType res;
	if (x > 20)
		return -x;
	if (x < -20)
		return 0;
	res = -log(1.0 + exp(x));
	return res;
}

} // namespace PsimagLite

/*@}*/
#endif // FERMI_H_
PsimagLite-3.06/src/FloatingPoint.h000066400000000000000000000057221446452427400172370ustar00rootroot00000000000000/*
Copyright (c) 2014, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file FloatingPoint.h
 *
 */
#ifndef PSI_FLOATING_POINT_H
#define PSI_FLOATING_POINT_H

#ifndef NDEBUG
#include 
#endif

namespace PsimagLite
{

class FloatingPoint
{

public:

	static void enableExcept()
	{
#ifndef NDEBUG
		feenableexcept(FE_DIVBYZERO | FE_INVALID);
#endif
	}
}; // class FloatingPoint

} // namespace PsimagLite

/*@}*/
#endif
PsimagLite-3.06/src/FreqEnum.h000066400000000000000000000002021446452427400161700ustar00rootroot00000000000000#ifndef PSI_FREQ_ENUM_H
#define PSI_FREQ_ENUM_H

namespace PsimagLite
{

enum FreqEnum { FREQ_REAL,
	FREQ_MATSUBARA };

}

#endif
PsimagLite-3.06/src/GemmR.h000066400000000000000000000100431446452427400154610ustar00rootroot00000000000000#ifndef PSI_GEMMR_H
#define PSI_GEMMR_H
#include "BLAS.h"
#include "Parallelizer2.h"
#include "Vector.h"
#include 

// Originally written by Ed

namespace PsimagLite
{

template 
class GemmR
{

public:

	GemmR(bool idebug, SizeType nb, SizeType nthreads)
	    : idebug_(idebug)
	    , nb_(nb)
	    , nthreads_(nthreads)
	{
	}

	void operator()(char const transA, char const transB, int const m, int const n, int const k, T const& alpha, T const* const A, int const ldA, T const* const B, int const ldB, T const& beta, T* const C, int const ldC)
	{
		if (isSmall(m, n)) {
			psimag::BLAS::GEMM(transA, transB, m, n, k, alpha, A, ldA, B, ldB, beta, C, ldC);
			return;
		}

		bigMatrices(transA, transB, m, n, k, alpha, A, ldA, B, ldB, beta, C, ldC);
	}

private:

	void bigMatrices(char const transA, char const transB, int const m, int const n, int const k, T const& alpha, T const* const A, int const ldA, T const* const B, int const ldB, T const& beta, T* const C, int const ldC)
	{
		assert(!isSmall(m, n));

		//  -------------------------
		//  if n = 101, and nb = 100,
		//  wish to avoid  one call with size 100
		//  and another call with size 1
		//  a more balanced work load is
		//  one call with size 51
		//  and one call with size 50
		//  -------------------------
		const SizeType nblocks_i = (m + (nb_ - 1)) / nb_;
		const SizeType nblocks_j = (n + (nb_ - 1)) / nb_;
		int const nb_i = ((m % nblocks_i) == 0) ? (m / nblocks_i)
							: ((m / nblocks_i) + 1);
		int const nb_j = ((n % nblocks_j) == 0) ? (n / nblocks_j)
							: ((n / nblocks_j) + 1);

		bool const is_transA = (transA == 'T') || (transA == 't');
		bool const is_conjA = (transA == 'C') || (transA == 'c');
		bool const is_notransA = (!is_transA) && (!is_conjA);

		bool const is_transB = (transB == 'T') || (transB == 't');
		bool const is_conjB = (transB == 'C') || (transB == 'c');
		bool const is_notransB = (!is_transB) && (!is_conjB);

		if (idebug_ >= 1) {
			std::cout << " GEMMR: "
				  << " m " << m << " n " << n << " k " << k
				  << " nb " << nb_ << " nb_i " << nb_i
				  << " nb_j " << nb_j << " nblocks_i "
				  << nblocks_i << " nblocks_j " << nblocks_j
				  << "\n";
		}

		auto lambda = [transA, transB, m, n, k, alpha, &A, ldA, &B, ldB, beta, &C, ldC, nblocks_i, nb_i, nb_j, is_notransA, is_notransB](SizeType ij_block, SizeType) {
			const SizeType i_block = (ij_block % nblocks_i);
			const SizeType j_block = (ij_block - i_block) / nblocks_i;
			assert((i_block + j_block * nblocks_i) == ij_block);

			int const ic_start = 1 + (i_block)*nb_i;
			int const ic_end = std::min(m, ic_start + nb_i - 1);
			int const jc_start = 1 + (j_block)*nb_j;
			int const jc_end = std::min(n, jc_start + nb_j - 1);

			// --------------------------------------------
			// compute   C(ic_start:ic_end, jc_start:jc_end) =
			//              A(ic_start:ic_end, 1:k) * B( 1:k,
			//              jc_start:jc_end)
			// --------------------------------------------

			int const mm = (ic_end - ic_start + 1);
			int const nn = (jc_end - jc_start + 1);

			// -----------------
			// no splitting in k
			// -----------------
			int const kk = k;

			int const ia = (is_notransA) ? ic_start : 1;
			int const ja = (is_notransA) ? 1 : ic_start;

			int const ib = (is_notransB) ? 1 : jc_start;
			int const jb = (is_notransB) ? jc_start : 1;

			int const ic = ic_start;
			int const jc = jc_start;

			T const* const pA = &(A[ia - 1 + (ja - 1) * ldA]);
			T const* const pB = &(B[ib - 1 + (jb - 1) * ldB]);
			T* const pC = &(C[ic - 1 + (jc - 1) * ldC]);

			psimag::BLAS::GEMM(transA, transB, mm, nn, kk, alpha, pA, ldA, pB, ldB, beta, pC, ldC);
		};

		const SizeType tasks = nblocks_i * nblocks_j;
		CodeSectionParams csp = Concurrency::codeSectionParams;
		csp.npthreads = std::min(tasks, nthreads_);
		Parallelizer2<> parallelizer2(csp);
		parallelizer2.parallelFor(0, tasks, lambda);
	}

	bool isSmall(SizeType m, SizeType n) const
	{
		if (nb_ == 0)
			return true;
		return ((m <= nb_) && (n <= nb_));
	}

	bool idebug_;
	SizeType nb_;
	SizeType nthreads_;
}; // class GemmR

} // namespace PsimagLite

#endif
PsimagLite-3.06/src/Geometry/000077500000000000000000000000001446452427400160765ustar00rootroot00000000000000PsimagLite-3.06/src/Geometry/Geometry.h000066400000000000000000000237241446452427400200520ustar00rootroot00000000000000/*
Copyright (c) 2009-2103, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file Geometry.h
 *
 *  DOC NEEDED FIXME
 */
#ifndef GEOMETRY_H
#define GEOMETRY_H

#include "GeometryEx.h"
#include "GeometryTerm.h"
#include "Io/IoSerializerStub.h"

namespace PsimagLite
{

template 
class Geometry
    : public GeometryEx::Type, InputType_>
{

public:

	typedef ComplexOrRealType_ ComplexOrRealType;
	typedef InputType_ InputType;
	typedef typename Real::Type RealType;
	typedef GeometryTerm GeometryTermType;
	typedef typename Vector::Type VectorSizeType;
	typedef GeometryEx::Type, InputType>
	    GeometryExType;

	/** @class hide_geometry1
		- TotalNumberOfSites=integer This is the total number of sites
	   including bath sites (if any) and all system and environment sites.
		- NumberOfTerms=integer This is the number of Hamiltonian
	   off-site terms. This number must match the model's expected number of
	   terms. Note that each Hamiltonian off-site term can have a different
	   geometry!
	*/
	Geometry(InputType& io, bool debug = false, SizeType meshPoints = 0)
	    : GeometryExType(io, meshPoints)
	{
		int x;
		io.readline(x, "TotalNumberOfSites=");
		if (x < 0)
			throw RuntimeError(
			    "TotalNumberOfSites<0 is an error\n");
		linSize_ = x;

		io.readline(x, "NumberOfTerms=");
		if (x < 0)
			throw RuntimeError("NumberOfTerms<0 is an error\n");

		terms_.resize(x, 0);

		for (SizeType i = 0; i < terms_.size(); i++) {
			typename GeometryTermType::Auxiliary aux(
			    false, i, terms_.size(), linSize_);
			terms_[i] = new GeometryTermType(io, aux);
		}
	}

	~Geometry()
	{
		for (SizeType i = 0; i < terms_.size(); i++)
			if (terms_[i])
				delete terms_[i];
	}

	static String import()
	{
		String str("");
		str += "integer TotalNumberOfSites;\n";
		str += "integer NumberOfTerms;\n";
		str += GeometryTermType::import();

		return str;
	}

	void write(PsimagLite::String label, IoSerializer& ioSerializer) const
	{
		ioSerializer.createGroup(label);
		ioSerializer.write(label + "/linSize_", linSize_);
		ioSerializer.write(label + "/terms_", terms_);
	}

	String label(SizeType i) const { return terms_[i]->label(); }

	typename ProgramGlobalsType::ConnectionEnum
	connectionKind(SizeType smax, SizeType ind, SizeType jnd) const
	{
		SizeType middle = smax + 1;
		if (ind < middle && jnd >= middle)
			return ProgramGlobalsType::ConnectionEnum::
			    SYSTEM_ENVIRON;
		if (jnd < middle && ind >= middle)
			return ProgramGlobalsType::ConnectionEnum::
			    ENVIRON_SYSTEM;
		return (ind < middle)
		    ? ProgramGlobalsType::ConnectionEnum::SYSTEM_SYSTEM
		    : ProgramGlobalsType::ConnectionEnum::
			ENVIRON_ENVIRON;
	}

	ComplexOrRealType operator()(SizeType smax, SizeType emin, SizeType i1, SizeType edof1, SizeType i2, SizeType edof2, SizeType term) const
	{
		assert(term < terms_.size());
		return (smax + 1 == emin)
		    ? terms_[term]->operator()(i1, edof1, i2, edof2)
		    : terms_[term]->operator()(smax, emin, i1, edof1, i2, edof2);
	}

	ComplexOrRealType operator()(SizeType i1, SizeType edof1, SizeType i2, SizeType edof2, SizeType term) const
	{
		return terms_[term]->operator()(i1, edof1, i2, edof2);
	}

	bool connected(SizeType smax, SizeType emin, SizeType i1, SizeType i2) const
	{
		bool b = false;

		if (smax + 1 == emin) {
			for (SizeType t = 0; t < terms_.size(); ++t)
				b |= terms_[t]->connected(i1, i2);
			return b;
		}

		for (SizeType t = 0; t < terms_.size(); ++t)
			b |= terms_[t]->connected(smax, emin, i1, i2);
		return b;
	}

	SizeType terms() const { return terms_.size(); }

	SizeType numberOfSites() const { return linSize_; }

	SizeType orbitals(SizeType term, SizeType site) const
	{
		assert(term < terms_.size());
		return terms_[term]->orbitals(site);
	}

	void split(SizeType sitesPerBlock, VectorSizeType& S, typename Vector::Type& X, typename Vector::Type& Y, VectorSizeType& E, bool allInSystem = false) const
	{
		SizeType middle = linSize_ / 2;
		if (linSize_ & 1) {
			std::cerr << "EXPERIMENTAL: Geometry::split(...): ";
			std::cerr << " Lattice is odd (it has " << linSize_
				  << " sites).\n";
			middle++;
		}

		bool b1 = ((linSize_ % sitesPerBlock) != 0);
		b1 |= (static_cast(linSize_ / sitesPerBlock) < 3);
		bool b2 = (sitesPerBlock > 1);
		if (b1 && b2) {
			String str(__FILE__);
			str += " " + ttos(__LINE__) + "\n";
			str += "split error, linSize_=" + ttos(linSize_);
			str += " sitesPerBlock=" + ttos(sitesPerBlock) + "\n";
			throw RuntimeError(str.c_str());
		}

		SizeType i = 0;
		while (i < sitesPerBlock) {
			S.push_back(i);
			i++;
		}

		while (i < middle) {
			typename Vector::Type tmpV(sitesPerBlock);
			for (SizeType j = 0; j < sitesPerBlock; j++)
				tmpV[j] = i + j;
			X.push_back(tmpV);
			i += sitesPerBlock;
		}

		SizeType lastMiddle = linSize_ - sitesPerBlock;
		while (i < lastMiddle) {
			typename Vector::Type tmpV(sitesPerBlock);
			typename Vector::Type tmpV2(sitesPerBlock);
			for (SizeType j = 0; j < sitesPerBlock; j++) {
				SizeType jj = sitesPerBlock - 1 - j;
				tmpV[j] = (linSize_ - 1 - i - jj) + (middle - sitesPerBlock);
				tmpV2[j] = jj + i;
				assert(tmpV[j] < linSize_);
			}

			if (allInSystem)
				X.push_back(tmpV2);
			else
				Y.push_back(tmpV);
			i += sitesPerBlock;
		}

		while (i < linSize_) {
			E.push_back(i);
			i++;
		}
	}

	SizeType maxConnections(SizeType termId) const
	{
		return terms_[termId]->maxConnections();
	}

	SizeType maxConnections() const
	{
		SizeType result = 0;
		for (SizeType termId = 0; termId < terms_.size(); ++termId)
			if (terms_[termId]->maxConnections() > result)
				result = terms_[termId]->maxConnections();
		return result;
	}

	SizeType findReflection(SizeType site, SizeType termId) const
	{
		return terms_[termId]->findReflection(site);
	}

	SizeType length(SizeType i, SizeType termId) const
	{
		return terms_[termId]->length(i);
	}

	SizeType translate(SizeType site, SizeType dir, SizeType amount, SizeType termId) const
	{
		return terms_[termId]->translate(site, dir, amount);
	}

	void print(std::ostream& os) const
	{
		for (SizeType i = 0; i < terms_.size(); i++)
			terms_[i]->print(os, linSize_);
	}

	SizeType handle(SizeType t, SizeType ind, SizeType jnd) const
	{
		return terms_[t]->handle(ind, jnd);
	}

	SizeType directions(SizeType term) const
	{
		return terms_[term]->directions();
	}

	SizeType calcDir(SizeType term, SizeType i, SizeType j) const
	{
		assert(term < terms_.size());
		return terms_[term]->calcDir(i, j);
	}

	String options(SizeType term) const
	{
		assert(term < terms_.size());
		return terms_[term]->options();
	}

	// extended functions in GeometryEx

	// friends
	template 
	friend std::ostream&
	operator<<(std::ostream& os,
	    const Geometry& g);

private:

	SizeType linSize_;
	typename Vector::Type terms_;
}; // class Geometry

template 
std::ostream&
operator<<(std::ostream& os,
    const Geometry& g)
{
	os << "#GeometrySize=" << g.linSize_ << "\n";
	os << "#GeometryTerms=" << g.terms_.size() << "\n";
	for (SizeType i = 0; i < g.terms_.size(); i++)
		os << *(g.terms_[i]);
	return os;
}
} // namespace PsimagLite

/*@}*/
#endif // GEOMETRY_H
PsimagLite-3.06/src/Geometry/GeometryBase.h000066400000000000000000000116401446452427400206370ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file GeometryBase.h
 *
 *  Well, I need to read that chapter in
 *  Alexandrescu's "Modern C++ design" again to have
 *  a decent factory here, but this will have to do for now
 *
 */
#ifndef GEOMETRY_BASE_H
#define GEOMETRY_BASE_H

#include "InputNg.h"

namespace PsimagLite
{

template 
class GeometryBase
{

	typedef std::pair PairType;
	typedef Matrix MatrixType;

public:

	virtual ~GeometryBase() { }

	template 
	void write(Archive&, const unsigned int) { }

	virtual SizeType dirs() const = 0;

	virtual SizeType handle(SizeType i, SizeType j) const = 0;

	virtual SizeType getVectorSize(SizeType dirId) const = 0;

	virtual bool connected(SizeType i1, SizeType i2) const = 0;

	virtual SizeType calcDir(SizeType i1, SizeType i2) const = 0;

	virtual bool fringe(SizeType i, SizeType smax, SizeType emin) const = 0;

	virtual SizeType getSubstituteSite(SizeType smax, SizeType emin, SizeType siteNew2) const = 0;

	virtual String label() const = 0;

	virtual SizeType length(SizeType i) const = 0;

	virtual SizeType translate(SizeType site, SizeType dir, SizeType amount) const = 0;

	virtual SizeType maxConnections() const = 0;

	virtual SizeType findReflection(SizeType site) const = 0;

	virtual void set(MatrixType&, SizeType) const
	{
		throw RuntimeError(
		    "GeometryBase::set() unimplemented for derived class\n");
	}

	virtual int index(SizeType i1, SizeType edof1, SizeType edofTotal) const
	{
		assert(edof1 < edofTotal);
		return edof1 + i1 * edofTotal;
	}

	virtual SizeType matrixRank(SizeType linSize, SizeType maxEdof) const
	{
		return linSize * maxEdof;
	}

	virtual int signChange(SizeType, SizeType) const { return 1; }

	virtual SizeType orbitals(SizeType orbs, SizeType) const
	{
		return orbs;
	}

protected:

	SizeType unimplemented(const String& str) const
	{
		String str2 = "unimplemented " + str + "\n";
		throw RuntimeError(str2);
	}

	bool neighbors(SizeType i1, SizeType i2, bool periodic, SizeType period) const
	{
		SizeType imin = (i1 < i2) ? i1 : i2;
		SizeType imax = (i1 > i2) ? i1 : i2;
		bool b = (imax - imin == 1);
		if (!periodic)
			return b;
		bool b2 = (imax - imin == period);
		return (b || b2);
	}
}; // class GeometryBase
} // namespace PsimagLite

/*@}*/
#endif // GEOMETRY_BASE_H
PsimagLite-3.06/src/Geometry/GeometryDca.h000066400000000000000000000034221446452427400204530ustar00rootroot00000000000000/*
Copyright (c) 2014, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************

*/

#ifndef LANCZOS_GEOMETRY_DCA_H
#define LANCZOS_GEOMETRY_DCA_H
#include "Io/IoNg.h"
#include "Vector.h"

namespace PsimagLite
{

template 
class GeometryDca
{

public:

	typedef GeometryType_ GeometryType;
	typedef RealType_ RealType;

	GeometryDca(const GeometryType& g, SizeType orbitals)
	    : enabled_(false)
	    , message_(g.label(0) + " with " + ttos(orbitals))
	{
		if (g.label(0) == "star" && orbitals == 4)
			enabled_ = true;
	}

	SizeType kSum(SizeType k1, SizeType k2) const
	{
		if (!enabled_)
			printErrorAndDie("kSum");
		return (k1 ^ k2);
	}

	SizeType kSustract(SizeType k1, SizeType k2) const
	{
		if (!enabled_)
			printErrorAndDie("kSustract");
		return (k1 ^ k2);
	}

	void write(String label1, IoNg::Out::Serializer& io) const
	{
		String label = label1 + "/GeometryDca";
		io.createGroup(label);
		io.write(label + "/enabled_", enabled_);
		io.write(label + "/message_", message_);
	}

private:

	void printErrorAndDie(String func) const
	{
		String str("GeometryDca:: Only valid for 2x2 clusters\n");
		str += "Not for " + message_ + " orbitals.\n";
		str += "\tWhile calling function " + func + "\n";
		throw RuntimeError(str);
	}

	bool enabled_;
	String message_;
}; // class GeometryDca

} // namespace PsimagLite

#endif
PsimagLite-3.06/src/Geometry/GeometryDirection.h000066400000000000000000000171521446452427400217110ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 2.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file GeometryDirection.h
 *
 *  FIXME DOC. TBW
 */
#ifndef GEOMETRY_DIR_H
#define GEOMETRY_DIR_H
#include "Io/IoSerializerStub.h"
#include "Matrix.h"
#include 

namespace PsimagLite
{

template 
class GeometryDirection
{

	typedef Matrix MatrixType;
	typedef typename Real::Type RealType;

public:

	enum InternalDofEnum { GENERAL,
		SPECIFIC };

	struct Auxiliary {

		Auxiliary(bool c, SizeType d, InternalDofEnum idof_, SizeType orbitals_)
		    : constantValues(c)
		    , dirId(d)
		    , idof(idof_)
		    , orbitals(orbitals_)
		{
		}

		void write(PsimagLite::String label,
		    IoSerializer& ioSerializer) const
		{
			ioSerializer.createGroup(label);
			ioSerializer.write(label + "/constantValues",
			    constantValues);
			ioSerializer.write(label + "/dirId", dirId);
			ioSerializer.write(label + "/edof", idof);
		}

		bool constantValues;
		SizeType dirId;
		InternalDofEnum idof;
		SizeType orbitals;
	}; // struct Auxiliary

	template 
	GeometryDirection(IoInputter& io, const Auxiliary& aux, const GeometryBaseType* geometryFactory)
	    : aux_(aux)
	    , geometryBase_(geometryFactory)
	{
		SizeType n = (aux.idof == GENERAL) ? 0 : getVectorSize();

		if (aux.idof == GENERAL) {
			geometryBase_->set(rawHoppings_, aux.orbitals);
			return;
		}

		assert(aux.idof == SPECIFIC);

		String connectors = "Connectors";
		String savedPrefix = io.prefix();
		io.prefix() += "dir" + ttos(aux.dirId) + ":";

		if (aux.orbitals > 1) {
			if (n == 0)
				n = 1;
			for (SizeType i = 0; i < n; i++) {
				MatrixType m;
				String extraString = (n > 1 && io.version() > 2) ? ttos(i) : "";
				io.read(m, connectors + extraString);
				dataMatrices_.push_back(m);
				if (aux.orbitals != m.rows() || aux.orbitals != m.cols())
					throw RuntimeError(
					    "Connectors must be matrices of "
					    "rows=cols= "
					    + ttos(aux.orbitals) + "\n");
			}
		} else {
			io.read(dataNumbers_, connectors);
			if (dataNumbers_.size() != n) {
				String s(__FILE__);
				s += " " + ttos(dataNumbers_.size()) + " != " + ttos(n) + "\n";
				throw RuntimeError(s.c_str());
			}
		}

		io.prefix() = savedPrefix;
	}

	void write(PsimagLite::String label, IoSerializer& ioSerializer) const
	{
		ioSerializer.createGroup(label);
		aux_.write(label + "/aux_", ioSerializer);
		// geometryBase_
		ioSerializer.write(label + "/dataNumbers_", dataNumbers_);
		ioSerializer.write(label + "/dataMatrices_", dataMatrices_);
		rawHoppings_.write(label + "/rawHoppings_", ioSerializer);
	}

	template 
	SizeType memResolv(SomeMemResolvType&, SizeType, String) const
	{
		return 0;
	}

	ComplexOrRealType operator()(SizeType i, SizeType edof1, SizeType j, SizeType edof2) const
	{
		SizeType ii = edof1 + i * aux_.orbitals;
		SizeType jj = edof2 + j * aux_.orbitals;
		if (aux_.idof == GENERAL) {
			assert(edof1 < aux_.orbitals && edof2 < aux_.orbitals);
			return rawHoppings_(ii, jj);
		}

		assert(aux_.idof == SPECIFIC);

		SizeType h = (constantValues()) ? 0 : geometryBase_->handle(i, j);

		bool isMatrix = (aux_.orbitals > 1);
		if (!isMatrix) {
			assert(dataNumbers_.size() > h);
			return dataNumbers_[h];
		}

		if (ii < jj)
			return PsimagLite::conj(operator()(j, edof2, i, edof1));

		assert(dataMatrices_.size() > h);

		bool b = (dataMatrices_[h].rows() > edof1 && dataMatrices_[h].cols() > edof2);

		assert(b || (dataMatrices_[h].rows() > edof2 && dataMatrices_[h].cols() > edof1));

		ComplexOrRealType tmp = (b) ? dataMatrices_[h](edof1, edof2)
					    : dataMatrices_[h](edof2, edof1);
		int signChange = geometryBase_->signChange(i, j);
		return tmp * static_cast(signChange);
	}

	bool constantValues() const { return aux_.constantValues; }

	friend std::ostream& operator<<(std::ostream& os, const Auxiliary& a)
	{
		os << "constantValues=" << a.constantValues << "\n";
		os << "dirId=" << a.dirId << "\n";
		os << "edof=" << a.idof << "\n";

		return os;
	}

	friend std::ostream& operator<<(std::ostream& os,
	    const GeometryDirection& gd)
	{
		os << "#GeometryDirectionAuxiliary\n";
		os << gd.aux_;

		bool isMatrix = (gd.aux_.orbitals > 1 || gd.aux_.idof == SPECIFIC);

		if (!isMatrix) {
			os << "#GeometryNumbersSize=" << gd.dataNumbers_.size()
			   << "\n";
			os << "#GeometryNumbers=";
			for (SizeType i = 0; i < gd.dataNumbers_.size(); i++) {
				os << gd.dataNumbers_[i] << " ";
			}
			os << "\n";
		} else {
			os << "#GeometryMatrixSize=" << gd.dataMatrices_.size()
			   << "\n";
			for (SizeType i = 0; i < gd.dataMatrices_.size(); i++)
				os << gd.dataMatrices_[i];
		}
		return os;
	}

private:

	SizeType getVectorSize()
	{
		return (aux_.constantValues)
		    ? 1
		    : geometryBase_->getVectorSize(aux_.dirId);
	}

	Auxiliary aux_;
	const GeometryBaseType* geometryBase_;
	typename Vector::Type dataNumbers_;
	typename Vector::Type dataMatrices_;
	MatrixType rawHoppings_;
}; // class GeometryDirection
} // namespace PsimagLite

/*@}*/
#endif // GEOMETRY_DIR_H
PsimagLite-3.06/src/Geometry/GeometryEx.h000066400000000000000000000071321446452427400203420ustar00rootroot00000000000000#ifndef GEOMETRY_EX_H
#define GEOMETRY_EX_H

#include "Vector.h"

#ifndef USE_MS_GEOMETRY

namespace PsimagLite
{

template 
class GeometryEx
{

public:

	typedef typename Vector::Type VectorRealType;

	GeometryEx()
	    : meshLength_(0)
	    , enabled_(false)
	    , meshStep_(0)
	{
	}

	GeometryEx(InputType& io, SizeType meshPoints)
	    : meshLength_(static_cast(sqrt(meshPoints)))
	    , enabled_(false)
	    , meshStep_((meshLength_ > 0)
		      ? static_cast(2 * M_PI / meshLength_)
		      : 0)
	{
		String str;
		try {
			io.readline(str, "GeometryKind=", false);
		} catch (std::exception&) {
			io.readline(str, "gt0:GeometryKind=", false);
		}

		if (str == "star")
			enabled_ = true;
	}

	template 
	void write(Archive& ar, const unsigned int)
	{
		ar& meshLength_;
		ar& enabled_;
		ar& meshStep_;
	}

	template 
	SizeType memResolv(SomeMemResolvType& mres, SizeType x, String msg) const
	{
		String str = msg;
		str += "GeometryEx";
		const char* start = (const char*)&meshLength_;
		const char* end = (const char*)&enabled_;
		SizeType total = mres.memResolv(&meshLength_, end - start, str + " meshLength");

		start = end;
		end = (const char*)&meshStep_;
		total += mres.memResolv(&enabled_, end - start, str + " enabled");

		assert(x > total);
		total += mres.memResolv(&meshStep_, x - total, str + " meshStep");

		return total;
	}

	SizeType dimension(SizeType = 0) const
	{
		assert(enabled_);
		return 2;
	}

	void index2Rvector(SizeType, VectorRealType& rvector) const
	{
		assert(enabled_);
		rvector.resize(2);
		rvector[0] = 0;
		rvector[1] = 0;
	}

	void index2Kvector(SizeType, VectorRealType& kvector) const
	{
		assert(enabled_);
		kvector.resize(2);
		kvector[0] = 0;
		kvector[1] = 0;
	}

	//! Number of symmetry operations for this K Geometry.
	SizeType nGroupK() const
	{
		assert(enabled_);
		return 1;
	}

	SizeType ickequ(SizeType j, SizeType) const
	{
		assert(enabled_);
		return j;
	}

	void getMeshVector(VectorRealType& kvector, SizeType k) const
	{
		assert(enabled_);
		int k1 = k;
		int m = meshLength_;
		div_t q = PsimagLite::div(k1, m);
		kvector[0] = -M_PI + q.quot * meshStep_;
		kvector[1] = -M_PI + q.rem * meshStep_;
	}

	SizeType sizeOfMesh() const
	{
		assert(enabled_);
		return meshLength_ * meshLength_;
	}

private:

	SizeType meshLength_;
	bool enabled_;
	RealType meshStep_;
};

} // namespace PsimagLite

#else

#include "msGeometry.h"

namespace PsimagLite
{

template 
class GeometryEx
{

public:

	typedef typename Vector::Type VectorRealType;

	GeometryEx(InputType& io, SizeType meshPoints)
	{
		SizeType ly = 2;
		SizeType lx = 2;
		std::cerr
		    << "WARNING: GeometryEx(): lattice of 2x2 hard wired\n";
		msGeometryInit2D(lx, 0, 0, ly, meshPoints);
	}

	~GeometryEx() { msGeometryEnd(); }

	SizeType dimension(SizeType i = 0) const { return msGeometryDim(); }

	void index2Rvector(SizeType r, VectorRealType& rvector) const
	{
		return msGeometryIndex2Rvector(r, rvector);
	}

	void index2Kvector(SizeType k, VectorRealType& kvector) const
	{
		return msGeometryIndex2Kvector(k, kvector);
	}

	//! Number of symmetry operations for this K Geometry.
	SizeType nGroupK() const { return msGeometryNgroupK(); }

	SizeType ickequ(SizeType j, SizeType op) const
	{
		return msGeometryIckequ(j, op);
	}

	void getMeshVector(VectorRealType& kvector, SizeType k) const
	{
		return msGeometryGetMeshVector(kvector, k);
	}

	SizeType sizeOfMesh() const { return msGeometrySizeOfMesh(); }
};

} // namespace PsimagLite
#endif

#endif // GEOMETRY_EX_H
PsimagLite-3.06/src/Geometry/GeometryTerm.h000066400000000000000000000333501446452427400206760ustar00rootroot00000000000000/*
Copyright (c) 2009-2013,2022, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 2.]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file GeometryTerm.h
 *
 * Each geometry term represents a Hamiltonian connection term of the form
 * X_{ij} A_i B_j, where A and B are operators and X_{ij} are numbers.
 * Note that on-site Hamiltonian terms aren't included in the geometry since
 * they're trivially handled by the DMRG algorithm.
 */
#ifndef GEOMETRY_TERM_H
#define GEOMETRY_TERM_H

#include "AST/ExpressionForAST.h"
#include "AST/PlusMinusMultiplyDivide.h"
#include "GeometryBase.h"
#include "GeometryDirection.h"
#include "Honeycomb.h"
#include "KTwoNiFFour.h"
#include "Ladder.h"
#include "LadderBath.h"
#include "LadderX.h"
#include "LongChain.h"
#include "LongRange.h"
#include "PsimagLite.h"
#include "Star.h"
#include 

namespace PsimagLite
{

template 
class GeometryTerm
{

	typedef GeometryBase GeometryBaseType;
	typedef GeometryDirection
	    GeometryDirectionType;

public:

	typedef typename Real::Type RealType;
	typedef typename GeometryDirectionType::InternalDofEnum InternalDofEnum;

	struct Auxiliary {

		Auxiliary(bool d, SizeType t, SizeType n, SizeType l)
		    : debug(d)
		    , termId(t)
		    , numberOfTerms(n)
		    , linSize(l)
		{
		}

		void write(PsimagLite::String label,
		    IoSerializer& ioSerializer) const
		{
			ioSerializer.createGroup(label);
			ioSerializer.write(label + "/debug", debug);
			ioSerializer.write(label + "/termId", termId);
			ioSerializer.write(label + "/numberOfTerms",
			    numberOfTerms);
			ioSerializer.write(label + "/linSize", linSize);
		}

		bool debug;
		SizeType termId;
		SizeType numberOfTerms;
		SizeType linSize;
	}; // Auxiliary

	GeometryTerm()
	    : orbitals_(0)
	    , geometryBase_(0)
	{
	}

	/** @class hide_geometry2
	 - DegreesOfFreedom=integer Degrees of freedom on which the connectors
	 depend on.
	 - GeometryKind=string One of chain, chainEx, ladder, ladderx,
	 ladderbath, ktwoniffour, or star.
	 - GeometryOptions=string Either none or ConstantValues needs to explain
	 more FIXME
	*/
	GeometryTerm(InputType& io, const Auxiliary& aux)
	    : aux_(aux)
	    , orbitals_(1)
	    , geometryBase_(0)
	    , gOptions_("none")
	{
		String savedPrefix = io.prefix();
		io.prefix() += (aux.numberOfTerms > 1)
		    ? "gt" + ttos(aux.termId) + ":"
		    : "";

		InternalDofEnum idof = GeometryDirectionType::SPECIFIC;

		// legacy input files:
		SizeType x = orbitals_;
		try {
			io.readline(x, "DegreesOfFreedom=");
			orbitals_ = x;
		} catch (std::exception&) {
		}

		if (orbitals_ == 0)
			throw RuntimeError("DegreesOfFreedom=0 not allowed\n");

		String s;
		io.readline(s, "GeometryKind=");

		io.readline(gOptions_, "GeometryOptions=");
		bool constantValues = (gOptions_.find("ConstantValues") != String::npos);

		if (s == "chain" || s == "longchain") {
			geometryBase_ = new LongChain(
			    aux.linSize, io);
		} else if (s == "chainEx") {
			throw RuntimeError("GeometryTerm::ctor(): ChainEx: no "
					   "longer supported.\n");
		} else if (s == "ladder") {
			geometryBase_ = new Ladder(
			    aux.linSize, io);
		} else if (s == "ladderx") {
			geometryBase_ = new LadderX(
			    aux.linSize, io);
		} else if (s == "ladderbath") {
			geometryBase_ = new LadderBath(
			    aux.linSize, io);
		} else if (s == "ktwoniffour") {
			geometryBase_ = new KTwoNiFFour(
			    aux.linSize, io);
		} else if (s == "star") {
			geometryBase_ = new Star(
			    aux.linSize, io);
		} else if (s == "LongRange" || s == "General") {
			geometryBase_ = new LongRange(
			    aux.linSize, io);
			idof = GeometryDirectionType::GENERAL;
		} else if (s == "Honeycomb") {
			geometryBase_ = new Honeycomb(
			    aux.linSize, io);
		} else if (s.substr(0, 5) == "Super") {
			std::cout << __FILE__ << " SuperGeometry " << s
				  << " detected\n";
			std::cerr << __FILE__ << " SuperGeometry " << s
				  << " detected\n";
			gOptions_ = s;
		} else {
			throw RuntimeError("Unknown geometry " + s + "\n");
		}

		const SizeType ndirs = (geometryBase_) ? geometryBase_->dirs() : 0;
		for (SizeType i = 0; i < ndirs; ++i) {
			typename GeometryDirectionType::Auxiliary aux(
			    constantValues, i, idof, orbitals_);

			directions_.push_back(
			    GeometryDirectionType(io, aux, geometryBase_));
		}

		bool hasModifier = false;
		try {
			String vModifier;
			io.readline(vModifier, "GeometryValueModifier=");
			hasModifier = true;
		} catch (std::exception&) {
		}

		if (hasModifier) {
			throw RuntimeError(
			    "GeometryValueModifier is no longer allowed\n");
		}

		cacheValues();

		io.prefix() = savedPrefix;

		if (aux.debug) {
			std::cerr << "Cached values:\n";
			std::cerr << cachedValues_;
			std::cerr << "-----------\n";
		}
	}

	~GeometryTerm()
	{
		if (geometryBase_)
			delete geometryBase_;
	}

	void write(PsimagLite::String label, IoSerializer& ioSerializer) const
	{
		ioSerializer.createGroup(label);
		aux_.write(label + "/aux_", ioSerializer);
		ioSerializer.write(label + "/orbitals_", orbitals_);
		// geometryBase_->write(label + "/geometryBase_", ioSerializer);
		ioSerializer.write(label + "/gOptions_", gOptions_);
		ioSerializer.write(label + "/directions_", directions_);
		cachedValues_.write(label + "/cachedValues_", ioSerializer);
	}

	static String import()
	{
		String str("");

		static const SizeType maxTerms = 10;
		// last term is used to define entities without the prefix gt0:
		for (SizeType i = 0; i < maxTerms; ++i) {
			String istr = (i + 1 < maxTerms) ? "gt" + ttos(i) + ":" : "";
			str += "integer " + istr + "DegreesOfFreedom;\n";
			str += "string " + istr + "GeometryKind;\n";
			str += "string " + istr + "GeometryOptions;\n";
			str += "integer " + istr + "LadderLeg;\n";
			str += "integer " + istr + "LongChainDistance;\n";
			str += "integer " + istr + "BathSitesPerSite;\n";
			str += "string " + istr + "GeometryValueModifier;\n";
			for (SizeType j = 0; j < 9; ++j) {
				String jstr = "dir" + ttos(j) + ":";
				str += "vector " + istr + jstr + "Connectors;\n";
			}
		}

		return str;
	}

	template 
	void write(Archive&, const unsigned int) { }

	template 
	SizeType memResolv(SomeMemResolvType&, SizeType, String) const
	{
		return 0;
	}

	const ComplexOrRealType& operator()(SizeType i1, SizeType edof1, SizeType i2, SizeType edof2) const
	{
		assert(geometryBase_);
		int k1 = geometryBase_->index(i1, edof1, orbitals_);
		int k2 = geometryBase_->index(i2, edof2, orbitals_);
		assert(k1 >= 0 && k2 >= 0);
		return cachedValues_(k1, k2);
	}

	// assumes 1fringe(i1, smax, emin) && geometryBase_->fringe(i2, smax, emin));
		SizeType siteNew1 = i1;
		SizeType siteNew2 = i2;
		SizeType edofNew1 = edof1;
		SizeType edofNew2 = edof2;
		if (bothFringe) {
			if (i2 < i1) {
				siteNew1 = i2;
				siteNew2 = i1;
				edofNew1 = edof2;
				edofNew2 = edof1;
			}

			siteNew2 = geometryBase_->getSubstituteSite(smax, emin, siteNew2);
		}

		return operator()(siteNew1, edofNew1, siteNew2, edofNew2);
	}

	bool connected(SizeType smax, SizeType emin, SizeType i1, SizeType i2) const
	{
		if (i1 == i2)
			return false;

		assert(geometryBase_);
		bool bothFringe = (geometryBase_->fringe(i1, smax, emin) && geometryBase_->fringe(i2, smax, emin));

		if (!bothFringe)
			return geometryBase_->connected(i1, i2);
		// std::cerr<<"fringe= "<connected(i1, i2)
				       : false;
	}

	String label() const
	{
		assert(geometryBase_);
		return geometryBase_->label();
	}

	SizeType maxConnections() const
	{
		return (geometryBase_) ? geometryBase_->maxConnections() : 0;
	}

	SizeType findReflection(SizeType site) const
	{
		assert(geometryBase_);
		return geometryBase_->findReflection(site);
	}

	SizeType length(SizeType i) const
	{
		assert(geometryBase_);
		return geometryBase_->length(i);
	}

	SizeType translate(SizeType site, SizeType dir, SizeType amount) const
	{
		assert(geometryBase_);
		return geometryBase_->translate(site, dir, amount);
	}

	void print(std::ostream& os) const
	{
		SizeType linSize = aux_.linSize;

		os << "#orbital changes first\n";
		for (SizeType i = 0; i < linSize; i++) {
			SizeType dofsi = orbitals(i);
			for (SizeType dof1 = 0; dof1 < dofsi; dof1++) {
				for (SizeType j = 0; j < linSize; j++) {
					SizeType dofsj = orbitals(j);
					for (SizeType dof2 = 0; dof2 < dofsj;
					     dof2++) {
						if (!connected(i, j)) {
							os << 0 << " ";
							continue;
						}
						os << operator()(i, dof1, j, dof2)
						   << " ";
					}
				}

				os << "\n";
			}
		}
	}

	SizeType handle(SizeType ind, SizeType jnd) const
	{
		assert(geometryBase_);
		return geometryBase_->handle(ind, jnd);
	}

	SizeType directions() const
	{
		return (geometryBase_) ? geometryBase_->dirs() : 0;
	}

	SizeType calcDir(SizeType i, SizeType j) const
	{
		assert(geometryBase_);
		return geometryBase_->calcDir(i, j);
	}

	String options() const { return gOptions_; }

	friend std::ostream& operator<<(std::ostream& os,
	    const GeometryTerm& gt)
	{
		os << "#GeometryDirections=" << gt.directions_.size() << "\n";
		for (SizeType i = 0; i < gt.directions_.size(); i++)
			os << gt.directions_[i];
		gt.print(os);
		return os;
	}

	SizeType orbitals(SizeType site) const
	{
		assert(geometryBase_);
		return geometryBase_->orbitals(orbitals_, site);
	}

private:

	void cacheValues()
	{
		if (!geometryBase_)
			return;

		SizeType linSize = aux_.linSize;
		SizeType matrixRank = geometryBase_->matrixRank(linSize, orbitals_);
		cachedValues_.resize(matrixRank, matrixRank);

		for (SizeType i1 = 0; i1 < linSize; ++i1) {
			for (SizeType i2 = 0; i2 < linSize; ++i2) {
				if (!geometryBase_->connected(i1, i2))
					continue;
				for (SizeType edof1 = 0; edof1 < orbitals_;
				     edof1++) {
					int k1 = geometryBase_->index(
					    i1, edof1, orbitals_);
					if (k1 < 0)
						continue;
					for (SizeType edof2 = 0;
					     edof2 < orbitals_;
					     edof2++) {
						int k2 = geometryBase_->index(
						    i2, edof2, orbitals_);
						if (k2 < 0)
							continue;
						cachedValues_(k1, k2) = calcValue(i1, edof1, i2, edof2);
					}
				}
			}
		}
	}

	ComplexOrRealType calcValue(SizeType i1, SizeType edof1, SizeType i2, SizeType edof2) const
	{
		assert(geometryBase_);
		if (!geometryBase_->connected(i1, i2))
			return 0.0;

		SizeType dir = geometryBase_->calcDir(i1, i2);
		assert(dir < directions_.size());
		return directions_[dir](i1, edof1, i2, edof2);
	}

	GeometryTerm(const GeometryTerm&);

	GeometryTerm& operator=(const GeometryTerm&);

	Auxiliary aux_;
	SizeType orbitals_;
	GeometryBaseType* geometryBase_;
	String gOptions_;
	typename Vector::Type directions_;
	Matrix cachedValues_;
}; // class GeometryTerm
} // namespace PsimagLite

/*@}*/
#endif // GEOMETRY_TERM_H
PsimagLite-3.06/src/Geometry/Honeycomb.h000066400000000000000000000201301446452427400201660ustar00rootroot00000000000000/*
Copyright (c) 2009-2013-2018, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 2.]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file Honeycomb.h
 *
 *  HoneyComb lattice implementation (started March 2018)
 */
#ifndef PSI_GEOMETRY_HONEYCOMB_H
#define PSI_GEOMETRY_HONEYCOMB_H

#include "GeometryBase.h"
#include 
#include 

namespace PsimagLite
{

template 
class Honeycomb : public GeometryBase
{

public:

	enum Dir { DIR_X = 0,
		DIR_Y = 1,
		DIR_Z = 2 };
	enum GeLe { GREATER_OR_EQUAL,
		LESS_OR_EQUAL };

	Honeycomb(SizeType linSize, InputType& io)
	    : linSize_(linSize)
	    , periodicY_(false)
	    , periodicX_(false)
	{
		io.readline(ly_, "HoneycombLy=");
		int x = 0;
		io.readline(x, "IsPeriodicY=");
		periodicY_ = (x > 0);

		try {
			io.readline(x, "IsPeriodicX=");
			periodicX_ = (x > 0);
		} catch (std::exception&) {
		}
	}

	virtual SizeType maxConnections() const
	{
		// max connections broken when splitting the lattice
		return ly_ + 1; // overestimate probably
	}

	virtual SizeType dirs() const { return 3; }

	virtual SizeType length(SizeType) const
	{
		return this->unimplemented("length");
	}

	virtual SizeType translate(SizeType, SizeType, SizeType) const
	{
		return this->unimplemented("translate");
	}

	SizeType getVectorSize(SizeType dirId) const
	{
		throw RuntimeError(
		    "Honeycomb::getVectorSize() unimplemented\n");
	}

	bool connected(SizeType i1, SizeType i2) const
	{
		return connectedInternal(i1, i2).first;
	}

	// assumes i1 and i2 are connected
	SizeType calcDir(SizeType i1, SizeType i2) const
	{
		std::pair bdir = connectedInternal(i1, i2);
		assert(bdir.first);
		return bdir.second;
	}

	bool fringe(SizeType i, SizeType smax, SizeType emin) const
	{
		if (i <= smax)
			return isThereAneighbor(i, emin, linSize_);

		if (i >= emin)
			return isThereAneighbor(i, 0, smax);

		return false;
	}

	// assumes i1 and i2 are connected
	SizeType handle(SizeType i1, SizeType i2) const
	{
		throw RuntimeError("Honeycomb::handle() unimplemented\n");
	}

	// siteNew2 is fringe in the environment
	SizeType getSubstituteSite(SizeType smax, SizeType emin, SizeType siteNew2) const
	{
		throw RuntimeError(
		    "Honeycomb::getSubstituteSite() unimplemented\n");
	}

	String label() const { return "Honeycomb"; }

	SizeType findReflection(SizeType) const
	{
		throw RuntimeError("findReflection: unimplemented (sorry)\n");
	}

	template 
	void write(Archive&, const unsigned int) { }

private:

	std::pair connectedInternal(SizeType ii1, SizeType ii2) const
	{
		std::pair falseDir(false, DIR_X);
		if (ii1 == ii2)
			return falseDir;

		bool normal = (ii1 < ii2);
		SizeType i1 = (normal) ? ii1 : ii2;
		SizeType i2 = (normal) ? ii2 : ii1;

		SizeType x1 = 0;
		SizeType y1 = 0;
		getCoordinates(x1, y1, i1);

		SizeType x2 = 0;
		SizeType y2 = 0;
		getCoordinates(x2, y2, i2);

		if (isDirectionX(x1, y1, x2, y2))
			return std::pair(true, DIR_X);

		if (isDirectionY(x1, y1, x2, y2))
			return std::pair(true, DIR_Y);

		if (isDirectionZ(x1, y1, x2, y2))
			return std::pair(true, DIR_Z);

		return falseDir;
	}

	void getCoordinates(SizeType& x, SizeType& y, SizeType i) const
	{
		div_t q = PsimagLite::div(i, ly_);
		x = q.quot;
		y = q.rem;
	}

	// assumes i1 < i2
	bool isDirectionZ(SizeType x1, SizeType y1, SizeType x2, SizeType y2) const
	{
		if (x1 != x2)
			return false;
		assert(y1 < y2);
		SizeType d = y2 - y1;
		if ((d == 1) && (y1 & 1))
			return true;

		if (!periodicY_)
			return false;

		// periodic in y direction
		return (d + 1 == ly_);
	}

	// assumes i1 < i2
	bool isDirectionY(SizeType x1, SizeType y1, SizeType x2, SizeType y2) const
	{
		if (x1 == x2)
			return isDirectionYsameCol(y1, y2);

		SizeType dy = y2 - y1;
		if (dy != 1)
			return false;

		assert(x1 < x2);
		SizeType dx = x2 - x1;
		if ((dx == 1) && isMultipleOf3(y1) && (y2 < y1))
			return true;

		if (!periodicX_)
			return false;

		// periodic in x direction
		SizeType lx = linSize_ / ly_;
		if (dx + 1 != lx)
			return false;

		return (isMultipleOf3(y2) && (y1 < y2));
	}

	// assumes i1 < i2
	bool isDirectionX(SizeType x1, SizeType y1, SizeType x2, SizeType y2) const
	{
		if (x1 == x2)
			return isDirectionXsameCol(y1, y2);

		SizeType dy = y2 - y1;
		if (dy != 1)
			return false;

		assert(x1 < x2);
		SizeType dx = x2 - x1;
		if ((dx == 1) && isMultipleOf4(y1) && (y1 < y2))
			return true;

		if (!periodicX_)
			return false;

		// periodic in x direction
		SizeType lx = linSize_ / ly_;
		if (dx + 1 != lx)
			return false;

		return (isMultipleOf4(y2) && (y2 < y1));
	}

	bool isDirectionYsameCol(SizeType y1, SizeType y2) const
	{
		assert(y1 < y2);
		SizeType dy = y2 - y1;
		if (dy == 1 && isMultipleOf4(y1))
			return true;
		return (periodicY_ && (dy + 1 == ly_) && isMultipleOf4(y2));
	}

	bool isDirectionXsameCol(SizeType y1, SizeType y2) const
	{
		assert(y1 < y2);
		SizeType dy = y2 - y1;
		if (dy == 1 && is4nPlus2(y1))
			return true;
		return (periodicY_ && (dy + 1 == ly_) && is4nPlus2(y2));
	}

	bool isThereAneighbor(SizeType ind, SizeType start, SizeType end) const
	{
		for (SizeType i = start; i < end; ++i) {
			if (connectedInternal(ind, i).first)
				return true;
		}

		return false;
	}

	static bool isMultipleOf3(SizeType y) { return ((y % 3) == 0); }

	static bool isMultipleOf4(SizeType y) { return ((y % 4) == 0); }

	static bool is4nPlus2(SizeType y)
	{
		if (y < 2)
			return false;
		y -= 2;
		return ((y % 4) == 0);
	}

	SizeType linSize_;
	SizeType ly_;
	bool periodicY_;
	bool periodicX_;
};
} // namespace PsimagLite

/*@}*/
#endif // GEOMETRY_H
PsimagLite-3.06/src/Geometry/HowToConstructANewGeometry.txt000066400000000000000000000130031446452427400240700ustar00rootroot00000000000000HOW TO CONSTRUCT A NEW GEOMETRY:

(1) Understand the definition of geometry in DMRG++

(2) Write a class to contain your new geometry. 

(3) Implement the Geometry API.

(4) Hook up your geometry.

In detail now:

(1) Understand the definition of geometry in DMRG++

Start with N sites. N must be even. Label them from 0 to N-1.
Connect them with solid lines as you like to form a connected or disconnected graph. 
This is your geometry. Give it a name.

Definition: Connected sites: Sites i and j are connected in your geometry if you drew a line connecting
them. No site shall ever be connected to itself.

Definition: Absolute system: These are the lowest numbered N/2 sites.

Definition: Absolute environ: These are the highest numbered N/2 sites.

Definition: Absolute system fringe: All sites i in the absolute system such that there exists j in the 
absolute environ with i and j connected.

Definition: Absolute environ fringe: All sites i in the absolute environ such that there exists j in the 
absolute system with i and j connected.

Definition: Absolute fringe: The union of the absolute system fringe and absolute environ fringe.

Definition: System relative to smax: All sites less than and including smax.

Definition: Environ relative to emin: All sites greater than and including emin.

Definition: System fringe relative to smax: All sites i in the system relative to smax such that there exists j in the 
 environ relative to smax+1 with i and j connected.

Definition: Environ fringe relative to emin: All sites i in the environ relative to emin such that there exists j in the 
 system relative to emin-1 with i and j connected.

Definition: Direction: (abstract concept): 
Given the set of all connections (i,j) you can classify them according to "direction."
To the first class of connections give it the direction 0, to the second class give it the direction 1, etc.

For usual geometries you might want to associate direction with the usual direction given by assuming that there are
axes underlying your geometry. For example, one direction for chains, two directions for ladders, etc.

But you are allowed to choose the trivial category: all connections have direction 0.

Definition: Substitute site: (abstract concept): 
Because in DMRG the lattice is ``grown'' from smaller pieces (during the infinite loop), it is possible
to specify connections where none exist. For example, if you have a 100 site chain, and DMRG is putting it together
2 sites a time, and there are currently these sites:
0 -- 1 -- 2       97 --- 98 --- 99
then this gives disjoint lattices because there is no connection between sites 2 and 97.

DMRG++ geometries allow you to specify a substitute for site 97 (and, in general, for all the relative environ fringe)
for the purposes of connecting it (or them) to site 2 (and, in general, for all the relative system fringe).
Note that this depends on the stage of the infinite algorithm, specified by smax (in this case 2) and emin (in this case 97).
In this case it would be sensible to define:
getSubstituteSite(smax=2,emin=97,97) = 3.
So that 2 and 97 connect.

In general, you can specify any function, or, if you prefer to ignore this capability, then you can specify the
identity function. 

Enumeration of Connections: Handles.
If you have only one direction, then enumerate all your connections starting from 0 to Nc-1, where Nc is the number of connections.
For example, on a chain with 4 sites, there are 3 connections: (0,1), (1,2), (2,3), which can be labeled as 0, 1, 2.
For a chain then, handle(i,j) = min(i,j) is a valid enumeration of connections.

If you have more than one direccion, follow this process for every direction. So, you'll have connection 0, direction 0; connection 1,
direction 0; connection 2, direction 0; etc. Then you'll have connection 0, direction 1; connection 1, direction 1, etc.   
Again, this enumeration is on a direction by direction basis.

(2)  Write a class to contain your new geometry. 
Follow the example in Chain.h

(3)  Implement the API as follows:

// Returns the number of connections in direction dirId
SizeType getVectorSize(SizeType dirId) const;

// Are sites i1 and i2 connected? If yes, returns true, else returns false.
bool connected(SizeType i1,SizeType i2) const;

// Assuming that i1 and i2 are connected, returns the direction along
// which they are connected.
SizeType calcDir(SizeType i1,SizeType i2) const;

// Assume that the largest site of the system is smax, and
// that the smallest site of the environ is emin,
// Returns true if site i is in the relative fringe, else returns false.
bool fringe(SizeType i,SizeType smax,SizeType emin) const;

// Assume that the largest site of the system is smax, and
// that the smallest site of the environ is emin,
// Assume that site i is in the relative environ fringe.
// This function returns the substitute site for site i.
SizeType getSubstituteSite(SizeType smax,SizeType emin,SizeType i) const;

// Returns the name of this geometry
String label() const;

// Assume i and j are connected sites.
// This function returns the connection number on a direction by direction basis. 
SizeType handle(SizeType i,SizeType j) const;

// Returns the reflection of any site site of the lattice, considering a
// vertical reflection axis at the middle of the lattice.
// THIS FUNCTION IS DEPRECATED. YOUR GEOMETRY DOES NOT NEED TO BE REFLECTION SYMMETRIC
SizeType findReflection(SizeType site) const;


(4) Hook up your geometry.

Instantiate an object of your new geometry as a private
member of GeometryFactory.h. Add hooks following the Chain or Ladder example there.
PsimagLite-3.06/src/Geometry/KTwoNiFFour.h000066400000000000000000000231411446452427400203650ustar00rootroot00000000000000/*
Copyright (c) 2009-2012, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file KTwoNiFFour.h
 *
 *  DOC NEEDED FIXME
 */
#ifndef KTWONIFFOUR_H
#define KTWONIFFOUR_H
#include "GeometryBase.h"
#include 
#include 

namespace PsimagLite
{

template 
class KTwoNiFFour : public GeometryBase
{

	enum SubtypeEnum { SUBTYPE_X,
		SUBTYPE_Y };

	enum { DIR_X,
		DIR_Y,
		DIR_XPY,
		DIR_XMY };

public:

	enum TypeEnum { TYPE_O,
		TYPE_C };

	typedef std::pair PairType;
	typedef GeometryBase GeometryBaseType;

	KTwoNiFFour() { }

	KTwoNiFFour(SizeType linSize, InputType& io)
	    : linSize_(linSize)
	{
		io.readline(signChange_, "SignChange=");
		std::cout << "KTwoNiFFour: SIGN CHANGE=" << signChange_ << "\n";
	}

	SizeType getVectorSize(SizeType) const
	{
		assert(false);
		throw RuntimeError("getVectorSize: unimplemented\n");
	}

	virtual SizeType dirs() const { return 4; }

	virtual SizeType length(SizeType) const
	{
		return this->unimplemented("length");
	}

	virtual SizeType translate(SizeType, SizeType, SizeType) const
	{
		return this->unimplemented("translate");
	}

	bool connected(SizeType i1, SizeType i2) const
	{
		if (i1 == i2)
			return false;
		PairType type1 = findTypeOfSite(i1);
		PairType type2 = findTypeOfSite(i2);
		//! 4 possibilities
		//! c-c
		if (type1.first == type2.first && type1.first == TYPE_C)
			return false;
		//! o-o
		if (type1.first == type2.first && type1.first == TYPE_O) {
			if (type1.second == type2.second)
				return false;
			SizeType newi1 = (type1.second == SUBTYPE_X) ? i1 : i2;
			SizeType newi2 = (type1.second == SUBTYPE_X) ? i2 : i1;
			if (newi1 > newi2) {
				assert(newi1 >= 4);
				if (newi1 - 2 == newi2 || newi1 - 3 == newi2)
					return true;
				return false;
			}
			if (newi2 - 1 == newi1)
				return true;
			if (newi2 >= 2 && newi2 - 2 == newi1)
				return true;
			return false;
		}
		//! o-c or c-o
		SizeType newi1 = (type1.first == TYPE_O) ? i1 : i2;
		SizeType newi2 = (type1.first == TYPE_O) ? i2 : i1;
		assert(newi2 >= 3);
		if (newi2 - 1 == newi1 || newi2 - 2 == newi1 || newi2 - 3 == newi1 || newi2 + 1 == newi1)
			return true;
		return false;
	}

	// assumes i1 and i2 are connected
	SizeType calcDir(SizeType i1, SizeType i2) const
	{
		PairType type1 = findTypeOfSite(i1);
		PairType type2 = findTypeOfSite(i2);
		//! o-o
		if (type1.first == type2.first && type1.first == TYPE_O) {
			assert(type1.second != type2.second);
			SizeType newi1 = (type1.second == SUBTYPE_X) ? i1 : i2;
			SizeType newi2 = (type1.second == SUBTYPE_X) ? i2 : i1;
			if (newi1 > newi2) {
				assert(newi1 >= 4);
				SizeType distance = newi1 - newi2;
				if (distance == 2)
					return DIR_XPY;
				assert(distance == 3);
				return DIR_XMY;
			}
			SizeType distance = newi2 - newi1;
			if (distance == 1)
				return DIR_XPY;
			assert(distance == 2);
			return DIR_XMY;
		}
		//! o-c or c-o
		SizeType newi1 = (type1.first == TYPE_O) ? i1 : i2;
		type1 = findTypeOfSite(newi1);
		return (type1.second == SUBTYPE_X) ? DIR_X : DIR_Y;
	}

	bool fringe(SizeType i, SizeType smax, SizeType emin) const
	{
		SizeType r = smax % 4;
		switch (r) {
		case 0:
			return fringe0(i, smax, emin);
		case 1:
			return fringe1(i, smax, emin);
		case 2:
			return fringe2(i, smax, emin);
		case 3:
			return fringe3(i, smax, emin);
		}
		assert(false);
		return false;
	}

	// assumes i1 and i2 are connected
	SizeType handle(SizeType, SizeType) const
	{
		assert(false);
		return 0;
	}

	// siteNew2 is fringe in the environment
	SizeType getSubstituteSite(SizeType smax, SizeType emin, SizeType siteNew2) const
	{
		SizeType r = smax % 4;
		switch (r) {
		case 0:
			return subs0(smax, emin, siteNew2);
		case 1:
			return subs1(smax, emin, siteNew2);
		case 2:
			return subs2(smax, emin, siteNew2);
		case 3:
			return subs3(smax, emin, siteNew2);
		}
		assert(false);
		return 0;
	}

	String label() const { return "KTwoNiFFour"; }

	SizeType maxConnections() const { return 6; }

	SizeType findReflection(SizeType) const
	{
		throw RuntimeError("findReflection: unimplemented (sorry)\n");
	}

	SizeType matrixRank(SizeType, SizeType) const
	{
		SizeType sites = linSize_;
		SizeType no = 0;
		SizeType nc = 0;
		for (SizeType i = 0; i < sites; i++) {
			SizeType type1 = findTypeOfSite(i).first;
			if (type1 == TYPE_C)
				nc++;
			else
				no++;
		}
		return 2 * no + nc;
	}

	// FIXME: GENERALIZE by using orbitals per type of site
	int index(SizeType i, SizeType orb, SizeType) const
	{
		SizeType type1 = findTypeOfSite(i).first;
		if (type1 == TYPE_C && orb > 0)
			return -1;
		if (type1 == TYPE_C || orb == 0)
			return i;
		SizeType sites = linSize_;
		SizeType tmp = (i + 1) / 4;
		assert(sites + i >= tmp);
		return sites + i - tmp;
	}

	int signChange(SizeType i1, SizeType i2) const
	{
		// change the sign of Cu-O
		SizeType newi1 = std::min(i1, i2);
		SizeType newi2 = std::max(i1, i2);
		PairType type1 = findTypeOfSite(newi1);
		PairType type2 = findTypeOfSite(newi2);
		int sign1 = 1;
		if (type1.first != type2.first) {

			int diff = newi2 - newi1;
			assert(diff == 1 || diff == 2 || diff == 3);
			if (diff < 2)
				sign1 = -1;
		}

		if (isInverted(i1) || isInverted(i2))
			return signChange_ * sign1;
		return sign1;
	}

	SizeType orbitals(SizeType orbs, SizeType site) const
	{
		PairType type1 = findTypeOfSite(site);
		return (type1.first == TYPE_C) ? 1 : orbs;
	}

	//! Given as a pair, first number is the type,
	//! If first number == TYPE_C then second number is bogus
	//! If first number == TYPE_O then second number is the subtype
	static PairType findTypeOfSite(SizeType site)
	{
		SizeType sitePlusOne = site + 1;
		SizeType r = sitePlusOne % 4;
		if (r == 0)
			return PairType(TYPE_C, SUBTYPE_X);

		return (r == 1) ? PairType(TYPE_O, SUBTYPE_X)
				: PairType(TYPE_O, SUBTYPE_Y);
	}

private:

	bool isInverted(SizeType i) const
	{
		SizeType j = i + 4;
		return ((j % 8) == 0);
	}

	bool fringe0(SizeType i, SizeType smax, SizeType emin) const
	{
		return (i == smax || i == emin);
	}

	SizeType subs0(SizeType smax, SizeType, SizeType) const
	{
		return smax + 3;
	}

	bool fringe1(SizeType i, SizeType smax, SizeType emin) const
	{
		bool b1 = (i == smax || i == smax - 1);
		bool b2 = (i == emin || i == emin + 1 || i == emin + 2);
		return (b1 || b2);
	}

	SizeType subs1(SizeType smax, SizeType emin, SizeType i) const
	{
		if (i == emin)
			return smax + 3;
		if (i == emin + 1)
			return smax + 2;
		if (i == emin + 2)
			return smax + 4;
		assert(false);
		return 0;
	}

	bool fringe2(SizeType i, SizeType smax, SizeType emin) const
	{
		return (i == smax - 2 || i == emin + 2);
	}

	SizeType subs2(SizeType smax, SizeType emin, SizeType i) const
	{
		assert(i == emin + 2);
		return smax + 1;
	}

	bool fringe3(SizeType i, SizeType smax, SizeType emin) const
	{
		return (i == emin || i == smax || i == smax - 1 || i == smax - 2);
	}

	SizeType subs3(SizeType smax, SizeType emin, SizeType i) const
	{
		assert(i == emin);
		return smax + 1;
	}

	SizeType linSize_;
	int signChange_;
}; // class KTwoNiFFour
} // namespace PsimagLite

/*@}*/
#endif // KTWONIFFOUR_H
PsimagLite-3.06/src/Geometry/Ladder.h000066400000000000000000000170511446452427400174460ustar00rootroot00000000000000/*
Copyright (c) 2009-2012, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 2.4.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/

/** \ingroup PsimagLite */
/*@{*/

/*! \file Ladder.h
 *
 *  DOC NEEDED FIXME
 */
#ifndef LADDER_H
#define LADDER_H

#include "GeometryBase.h"

namespace PsimagLite
{

template 
class Ladder : public GeometryBase
{

public:

	enum { DIRECTION_X,
		DIRECTION_Y };

	Ladder() { }

	Ladder(SizeType linSize, InputType& io)
	    : linSize_(linSize)
	    , isPeriodicX_(false)
	{

		io.readline(leg_, "LadderLeg=");
		if (leg_ != 2) {
			std::cerr << "WARNING: LadderLeg!=2 is experimental!\n";
		}

		try {
			int x = 0;
			io.readline(x, "IsPeriodicX=");
			isPeriodicX_ = (x > 0) ? true : false;
			std::cerr << "INFO: IsPeriodicX=" << isPeriodicX_
				  << "\n";
		} catch (std::exception&) {
		}

		try {
			int x = 0;
			io.readline(x, "IsPeriodicY=");
			isPeriodicY_ = (x > 0) ? true : false;
			if (leg_ == 2)
				throw RuntimeError("LadderLeg==2 cannot have "
						   "IsPeriodicY set\n");
			std::cerr << "INFO: IsPeriodicY=" << isPeriodicY_
				  << "\n";
		} catch (std::exception& e) {
			if (leg_ > 2)
				throw RuntimeError("LadderLeg>2 must have "
						   "IsPeriodicY= line\n");
		}

		if (leg_ == 2)
			isPeriodicY_ = false;

		if (linSize % leg_ != 0)
			throw RuntimeError(
			    "Ladder: leg must divide number of sites\n");
	}

	virtual SizeType maxConnections() const
	{
		return (isPeriodicX_) ? linSize_ : leg_ + 1;
	}

	virtual SizeType dirs() const { return 2; }

	SizeType getVectorSize(SizeType dirId) const
	{
		if (dirId == DIRECTION_X)
			return (isPeriodicX_) ? linSize_ : linSize_ - leg_;
		else if (dirId == DIRECTION_Y)
			return (isPeriodicY_) ? linSize_
					      : linSize_ - linSize_ / leg_;

		throw RuntimeError("Unknown direction\n");
	}

	bool connected(SizeType i1, SizeType i2) const
	{
		if (i1 == i2)
			return false;
		SizeType c1 = i1 / leg_;
		SizeType c2 = i2 / leg_;
		SizeType r1 = i1 % leg_;
		SizeType r2 = i2 % leg_;
		if (c1 == c2)
			return this->neighbors(r1, r2, isPeriodicY_, leg_ - 1);
		if (r1 == r2)
			return this->neighbors(c1, c2, isPeriodicX_, linSize_ / leg_ - 1);
		return false;
	}

	SizeType calcDir(SizeType i1, SizeType i2) const
	{
		assert(connected(i1, i2));
		return (sameColumn(i1, i2)) ? DIRECTION_Y : DIRECTION_X;
	}

	bool fringe(SizeType i, SizeType smax, SizeType emin) const
	{
		SizeType c = smax % leg_;
		SizeType r = 2 + 2 * c;
		if (c >= leg_ / 2)
			r = r - leg_;

		if (smax + 1 == emin)
			r = leg_; // finite loops

		bool a = (i < emin && i >= smax - r + 1);
		bool b = (i > smax && i <= emin + r - 1);
		return (a || b);
	}

	// siteEnv is fringe in the environment
	SizeType getSubstituteSite(SizeType smax, SizeType emin, SizeType siteEnv) const
	{
		if (smax + 1 == emin)
			return siteEnv; // finite loops

		SizeType c = smax % leg_;
		SizeType s = int(emin / leg_) - int(smax / leg_);
		assert(s > 0);
		if (c >= leg_ / 2)
			s--;
		return siteEnv - s * leg_;
	}

	SizeType handle(SizeType i1, SizeType i2) const
	{
		const SizeType dir = calcDir(i1, i2);
		const SizeType imin = (i1 < i2) ? i1 : i2;
		const SizeType imax = (i1 < i2) ? i2 : i1;
		const SizeType y = imin / leg_;
		switch (dir) {
		case DIRECTION_X:
			if (!isPeriodicX_)
				return imin;
			return (imin < leg_ && imax == imin + linSize_ - leg_)
			    ? imax
			    : imin;
		case DIRECTION_Y:
			if (!isPeriodicY_)
				return imin - y;
			return (imin % leg_ == 0 && imax == imin + leg_ - 1)
			    ? imax
			    : imin;
		}

		throw RuntimeError("handle: Unknown direction\n");
	}

	bool sameColumn(SizeType i1, SizeType i2) const
	{
		SizeType c1 = i1 / leg_;
		SizeType c2 = i2 / leg_;
		if (c1 == c2)
			return true;
		return false;
	}

	bool sameRow(SizeType i1, SizeType i2) const
	{
		SizeType c1 = i1 % leg_;
		SizeType c2 = i2 % leg_;
		if (c1 == c2)
			return true;
		return false;
	}

	String label() const { return "ladder"; }

	SizeType length(SizeType i) const
	{
		assert(i < 2);
		return (i == 1) ? leg_ : SizeType(linSize_ / leg_);
	}

	SizeType leg() const { return leg_; }

	SizeType translate(SizeType site, SizeType dir, SizeType amount) const
	{
		assert(dir < 2);
		SizeType x = SizeType(site / leg_);
		SizeType y = site % leg_;
		SizeType lx = SizeType(linSize_ / leg_);
		if (dir == DIRECTION_X)
			x = translateInternal(x, lx, amount);
		else
			y = translateInternal(y, leg_, amount);
		SizeType ind = y + x * leg_;
		assert(ind < linSize_);
		return ind;
	}

	SizeType findReflection(SizeType site) const
	{
		SizeType x = SizeType(site / leg_);
		SizeType y = site % leg_;
		SizeType lx = SizeType(linSize_ / leg_);
		SizeType ind = y + (lx - x - 1) * leg_;
		assert(ind < linSize_);
		return ind;
	}

	bool isPeriodicY() const { return isPeriodicY_; }

	bool isPeriodicX() const { return isPeriodicX_; }

private:

	SizeType translateInternal(SizeType c, SizeType l, SizeType amount) const
	{
		c += amount;
		while (c >= l)
			c -= l;
		return c;
	}

	SizeType linSize_;
	SizeType leg_;
	bool isPeriodicX_;
	bool isPeriodicY_;
}; // class Ladder
} // namespace PsimagLite

/*@}*/
#endif // LADDER_H
PsimagLite-3.06/src/Geometry/LadderBath.h000066400000000000000000000204741446452427400202500ustar00rootroot00000000000000/*
Copyright (c) 2009-2014, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/

/** \ingroup PsimagLite */
/*@{*/

/*! \file LadderBath.h
 *
 *  DOC NEEDED FIXME
 */
#ifndef LADDER_BATH_H
#define LADDER_BATH_H

#include "Ladder.h"

namespace PsimagLite
{

template 
class LadderBath : public GeometryBase
{

	typedef std::pair PairType;
	typedef Ladder LadderType;

public:

	enum {
		DIRECTION_X = LadderType::DIRECTION_X,
		DIRECTION_Y = LadderType::DIRECTION_Y,
		DIRECTION_BATH
	};

	LadderBath() { }

	LadderBath(SizeType linSize, InputType& io)
	    : linSize_(linSize)
	    , ladder_(0)
	{
		io.readline(bathSitesPerSite_, "BathSitesPerSite=");
		clusterSize_ = linSize_ / (1 + bathSitesPerSite_);

		ladder_ = new LadderType(clusterSize_, io);
	}

	~LadderBath()
	{
		if (ladder_)
			delete ladder_;
	}

	virtual SizeType dirs() const { return 3; }

	virtual SizeType length(SizeType) const
	{
		return this->unimplemented("length");
	}

	virtual SizeType translate(SizeType, SizeType, SizeType) const
	{
		return this->unimplemented("translate");
	}

	SizeType getVectorSize(SizeType dirId) const
	{
		if (dirId == DIRECTION_BATH)
			return bathSitesPerSite_ * clusterSize_;
		return ladder_->getVectorSize(dirId);
	}

	bool connected(SizeType i1, SizeType i2) const
	{
		if (i1 == i2)
			return false;
		int c1 = getClusterSite(i1).first;
		int c2 = getClusterSite(i2).first;
		// 4 possibilites
		//  1. both in the cluster
		if (c1 < 0 && c2 < 0)
			return connectedInCluster(i1, i2);
		// both in the bath:
		if (c1 >= 0 && c2 >= 0)
			return false;
		// cluster - bath
		if (c1 < 0) {
			return (SizeType(c2) == i1) ? true : false;
		}
		// bath - cluster
		return (SizeType(c1) == i2) ? true : false;
	}

	// assumes i1 and i2 are connected
	SizeType calcDir(SizeType i1, SizeType i2) const
	{
		int c1 = getClusterSite(i1).first;
		int c2 = getClusterSite(i2).first;
		// two possibilities
		// 1. both in the cluster
		if (c1 < 0 && c2 < 0)
			return calcDirInCluster(i1, i2);
		// cluster - bath or bath cluster:
		return DIRECTION_BATH;
	}

	bool fringe(SizeType i, SizeType smax, SizeType emin) const
	{
		int c = getClusterSite(i).first;
		if (c >= 0)
			return false; // no bath site is ever fringe
		return fringeInCluster(i, smax, emin);
	}

	// assumes i1 and i2 are connected
	SizeType handle(SizeType i1, SizeType i2) const
	{
		PairType c1 = getClusterSite(i1);
		PairType c2 = getClusterSite(i2);
		// two possibilities
		// 1. both in the cluster
		if (c1.first < 0 && c2.first < 0)
			return handleInCluster(i1, i2);
		// cluster - bath or bath cluster
		PairType x = (c1.first < 0) ? c2 : c1;
		if (x.first < 0 || x.second < 0)
			throw RuntimeError("Internal error in handle\n");
		SizeType firstClusterSite = (clusterSize_ / 2) * bathSitesPerSite_;
		x.first -= firstClusterSite;

		return x.first * bathSitesPerSite_ + x.second;
	}

	// siteNew2 is fringe in the environment
	SizeType getSubstituteSite(SizeType smax, SizeType emin, SizeType siteNew) const
	{
		PairType c1 = getClusterSite(siteNew);

		// in the cluster
		if (c1.first < 0) {
			SizeType firstClusterSite = (clusterSize_ / 2) * bathSitesPerSite_;
			SizeType siteNewCluster = siteNew - firstClusterSite;
			SizeType smaxCluster = smax - firstClusterSite;
			SizeType eminCluster = emin - firstClusterSite;
			SizeType siteSubs = ladder_->getSubstituteSite(
			    smaxCluster, eminCluster, siteNewCluster);
			return siteSubs + firstClusterSite;
		}

		String str(__FILE__);
		str += " " + ttos(__LINE__) + "Internal error in getSubstituteSite\n";
		throw RuntimeError(str);
	}

	String label() const { return "ladderbath"; }

	SizeType maxConnections() const { return clusterSize_ + 1; }

	SizeType findReflection(SizeType) const
	{
		throw RuntimeError("findReflection: unimplemented (sorry)\n");
	}

private:

	// if i is in the cluster return the pair (-1,-1)
	// else return the corresponding cluster site c and the number
	// of this bath site as a pair (c,b)
	PairType getClusterSite(SizeType i) const
	{
		SizeType firstClusterSite = (clusterSize_ / 2) * bathSitesPerSite_;
		SizeType lastP1ClusterSite = firstClusterSite + clusterSize_;
		if (i >= firstClusterSite && i < lastP1ClusterSite)
			return PairType(-1, -1);

		SizeType middle = linSize_ / 2;
		SizeType cs = clusterSize_ / 2;
		// now i is in the bath:
		if (i < middle) { // i is in the system
			return PairType(i % cs + firstClusterSite, i / cs);
		}
		// is in the bath and in the environ:
		SizeType iprime = i - lastP1ClusterSite;
		SizeType offset = lastP1ClusterSite - cs;
		return PairType(iprime % cs + offset, iprime / cs);
	}

	// assumes i1 and i2 are in the cluster
	// if connected return true, else false
	bool connectedInCluster(SizeType i1, SizeType i2) const
	{
		ladderize(i1, i2);
		return ladder_->connected(i1, i2);
	}

	// assumes i1 and i2 are connected and in the cluster
	SizeType calcDirInCluster(SizeType i1, SizeType i2) const
	{
		ladderize(i1, i2);
		return ladder_->calcDir(i1, i2);
	}

	// assumes i1 and i2 are in the cluster
	bool fringeInCluster(SizeType i, SizeType smax, SizeType emin) const
	{
		SizeType firstClusterSite = (clusterSize_ / 2) * bathSitesPerSite_;
		i -= firstClusterSite;
		smax -= firstClusterSite;
		emin -= firstClusterSite;
		return ladder_->fringe(i, smax, emin);
	}

	// assumes i1 and i2 are connected and in the cluster
	SizeType handleInCluster(SizeType i1, SizeType i2) const
	{
		ladderize(i1, i2);
		return ladder_->handle(i1, i2);
	}

	void ladderize(SizeType& i1, SizeType& i2) const
	{
		SizeType firstClusterSite = (clusterSize_ / 2) * bathSitesPerSite_;
		i1 -= firstClusterSite;
		i2 -= firstClusterSite;
	}

	SizeType linSize_;
	SizeType bathSitesPerSite_;
	SizeType clusterSize_;
	LadderType* ladder_;
}; // class LadderBath
} // namespace PsimagLite

/*@}*/
#endif // GEOMETRY_H
PsimagLite-3.06/src/Geometry/LadderX.h000066400000000000000000000134311446452427400175740ustar00rootroot00000000000000/*
Copyright (c) 2009-2013-2018, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 2.]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file LadderX.h
 *
 *  DOC NEEDED FIXME
 */
#ifndef LADDERX_H
#define LADDERX_H

#include "Ladder.h"
#include 

namespace PsimagLite
{

template 
class LadderX : public GeometryBase
{

	typedef Ladder LadderType;

public:

	enum {
		DIRECTION_X = LadderType::DIRECTION_X,
		DIRECTION_Y = LadderType::DIRECTION_Y,
		DIRECTION_XPY,
		DIRECTION_XMY
	};

	LadderX() { }

	LadderX(SizeType linSize, InputType& io)
	    : ladder_(linSize, io)
	    , linSize_(linSize)
	    , leg_(ladder_.leg())
	{
	}

	virtual SizeType maxConnections() const { return leg_ + 1; }

	virtual SizeType dirs() const { return 4; }

	virtual SizeType length(SizeType) const
	{
		return this->unimplemented("length");
	}

	virtual SizeType translate(SizeType, SizeType, SizeType) const
	{
		return this->unimplemented("translate");
	}

	SizeType getVectorSize(SizeType dirId) const
	{
		switch (dirId) {
		case DIRECTION_XPY:
			return linSize_ - leg_;
		case DIRECTION_XMY:
			return linSize_ - leg_;
		}

		return ladder_.getVectorSize(dirId);
	}

	bool connected(SizeType i1, SizeType i2) const
	{
		if (i1 == i2)
			return false;

		if (ladder_.connected(i1, i2))
			return true;

		SizeType lx = linSize_ / leg_;
		bool isPeriodicY = ladder_.isPeriodicY();
		SizeType c1 = i1 / leg_;
		SizeType c2 = i2 / leg_;
		SizeType r1 = i1 % leg_;
		SizeType r2 = i2 % leg_;

		if (c1 == c2)
			return this->neighbors(r1, r2, isPeriodicY, leg_);

		if (r1 == r2)
			return this->neighbors(c1, c2, false, 0);

		return (this->neighbors(r1, r2, isPeriodicY, leg_) && this->neighbors(c1, c2, isPeriodicY, lx));
	}

	// assumes i1 and i2 are connected
	SizeType calcDir(SizeType i1, SizeType i2) const
	{
		if (ladder_.sameColumn(i1, i2))
			return DIRECTION_Y;
		if (ladder_.sameRow(i1, i2))
			return DIRECTION_X;
		SizeType imin = (i1 < i2) ? i1 : i2;
		if (imin & 1)
			return DIRECTION_XPY;
		return DIRECTION_XMY;
	}

	bool fringe(SizeType i, SizeType smax, SizeType emin) const
	{
		bool a = (i < emin && i >= smax - 1);
		bool b = (i > smax && i <= emin + 1);
		if (smax & 1)
			return (a || b);
		a = (i < emin && i >= smax - 2);
		b = (i > smax && i <= emin + 2);
		return (a || b);
	}

	// assumes i1 and i2 are connected
	SizeType handle(SizeType i1, SizeType i2) const
	{
		SizeType dir = calcDir(i1, i2);
		SizeType imin = (i1 < i2) ? i1 : i2;
		switch (dir) {
		case DIRECTION_X:
			return imin;
		case DIRECTION_Y:
			return imin - imin / leg_;
		case DIRECTION_XPY: // only checked for leg_=2
			return (imin - 1) / leg_;
		case DIRECTION_XMY: // only checked for leg_=2
			return imin / leg_;
		}
		throw RuntimeError("handle: Unknown direction\n");
	}

	// siteNew2 is fringe in the environment
	SizeType getSubstituteSite(SizeType smax, SizeType emin, SizeType siteNew2) const
	{
		return smax + siteNew2 - emin + 1;
	}

	String label() const { return "ladderx"; }

	SizeType findReflection(SizeType) const
	{
		throw RuntimeError("findReflection: unimplemented (sorry)\n");
	}

private:

	LadderType ladder_; // owner
	SizeType linSize_;
	SizeType leg_;
}; // class LadderBath
} // namespace PsimagLite

/*@}*/
#endif // GEOMETRY_H
PsimagLite-3.06/src/Geometry/LongChain.h000066400000000000000000000127071446452427400201200ustar00rootroot00000000000000/*
Copyright (c) 2009-2014, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file LongChain.h
 *
 *  DOC NEEDED FIXME
 */
#ifndef PSI_GEOM_LONG_CHAIN_H
#define PSI_GEOM_LONG_CHAIN_H
#include "GeometryBase.h"

namespace PsimagLite
{

template 
class LongChain : public GeometryBase
{

public:

	enum { DIRECTION_X };

	LongChain()
	    : linSize_(0)
	    , isPeriodic_(false)
	    , distance_(1)
	{
	}

	LongChain(SizeType linSize, InputType& io)
	    : linSize_(linSize)
	    , isPeriodic_(false)
	    , distance_(1)
	{
		try {
			int x = 0;
			io.readline(x, "IsPeriodicX=");
			isPeriodic_ = (x > 0) ? true : false;
			if (isPeriodic_)
				std::cerr << "LongChain::ctor(): periodic\n";
		} catch (std::exception& e) {
		}

		try {
			int x = 0;
			io.readline(x, "LongChainDistance=");
			distance_ = x;
		} catch (std::exception& e) {
		}

		if (linSize_ <= distance_)
			RuntimeError("LongChain::ctor()\n");
	}

	virtual SizeType maxConnections() const
	{
		return (isPeriodic_) ? linSize_ : 1;
	}

	virtual SizeType dirs() const { return 1; }

	SizeType handle(SizeType i, SizeType j) const
	{
		return (i < j) ? i : j;
	}

	SizeType getVectorSize(SizeType dirId) const
	{
		assert(dirId == DIRECTION_X);
		const SizeType oneOrZero = (isPeriodic_) ? 1 : 0;
		return linSize_ - distance_ + oneOrZero;
	}

	bool connected(SizeType i1, SizeType i2) const
	{
		if (i1 == i2)
			return false;
		SizeType imin = (i1 < i2) ? i1 : i2;
		SizeType imax = (i1 > i2) ? i1 : i2;
		bool b = (imax - imin == distance_);
		if (!isPeriodic_)
			return b;
		bool b2 = (imax - imin == linSize_ - distance_);
		return (b || b2);
	}

	// assumes i1 and i2 are connected
	SizeType calcDir(SizeType, SizeType) const { return DIRECTION_X; }

	bool fringe(SizeType i, SizeType smax, SizeType emin) const
	{
		SizeType emin2 = smax + 1;
		if (i <= smax) {
			SizeType iPlus = i + distance_;
			return (iPlus < linSize_ && iPlus >= emin2);
		}

		return (i >= distance_ && (i - distance_) < emin);
	}

	// siteNew2 is fringe in the environment
	SizeType getSubstituteSite(SizeType smax, SizeType emin, SizeType siteNew2) const
	{
		assert(siteNew2 >= emin);
		SizeType tmp = siteNew2 - emin + smax + 1;
		assert(tmp < linSize_);
		return tmp;
	}

	String label() const { return "longchain"; }

	SizeType findReflection(SizeType site) const
	{
		return linSize_ - site - 1;
	}

	SizeType length(SizeType i) const
	{
		assert(i == 0);
		return linSize_;
	}

	SizeType translate(SizeType site, SizeType dir, SizeType amount) const
	{
		assert(dir == 0);

		site += amount;
		while (site >= linSize_)
			site -= linSize_;
		return site;
	}

	template 
	void write(Archive&, const unsigned int)
	{
		throw RuntimeError("LongChain::write(): unimplemented\n");
	}

private:

	SizeType linSize_;
	bool isPeriodic_;
	SizeType distance_;
}; // class LongChain
} // namespace PsimagLite

/*@}*/
#endif // LADDER_H
PsimagLite-3.06/src/Geometry/LongRange.h000066400000000000000000000156251446452427400201340ustar00rootroot00000000000000/*
Copyright (c) 2009-2014, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file LongRange.h
 *
 *  DOC NEEDED FIXME
 */
#ifndef PSI_GEOM_LONG_RANGE_H
#define PSI_GEOM_LONG_RANGE_H
#include "GeometryBase.h"

namespace PsimagLite
{

template 
class LongRange : public GeometryBase
{

	typedef Matrix MatrixType;

public:

	LongRange()
	    : linSize_(0)
	    , orbitals_(0)
	    , maxConnections_(0)
	{
	}

	LongRange(SizeType linSize, InputType& io)
	    : linSize_(linSize)
	    , maxConnections_(0)
	{
		bool hasEntangler = false;
		typename Real::Type entangler = 0;

		try {
			io.readline(entangler, "GeometryEntangler=");
			hasEntangler = true;
		} catch (std::exception&) {
		}

		if (hasEntangler) {
			SizeType orbitals = 0;
			io.readline(orbitals, "Orbitals=");
			const SizeType n = orbitals * linSize;
			matrix_.resize(n, n);
			setEntangler(entangler);
		} else {
			io.read(matrix_, "Connectors");
		}

		checkConnectors(matrix_, linSize_);

		orbitals_ = matrix_.rows() / linSize;

		try {
			io.readline(maxConnections_, "GeometryMaxConnections=");
		} catch (std::exception& e) {
			if (!hasEntangler) {
				std::cerr
				    << "Please add GeometryMaxConnections=0 or "
				       "some other number\n";
				throw e;
			}
		}
	}

	virtual void set(MatrixType& m, SizeType orbitals) const
	{
		m = matrix_;
		if (orbitals != orbitals_)
			throw RuntimeError(
			    "General geometry connectors: wrong size\n");
	}

	virtual SizeType maxConnections() const
	{
		return (maxConnections_ == 0) ? linSize_ * linSize_ * 0.25
					      : maxConnections_;
	}

	virtual SizeType dirs() const { return 1; }

	SizeType handle(SizeType i, SizeType j) const
	{
		return (i < j) ? i : j;
	}

	SizeType getVectorSize(SizeType dirId) const
	{
		assert(dirId == 0);
		throw RuntimeError(
		    "LongRange::getVectorSize(): unimplemented\n");
	}

	bool connected(SizeType i1, SizeType i2) const { return true; }

	// assumes i1 and i2 are connected
	SizeType calcDir(SizeType, SizeType) const { return 0; }

	bool fringe(SizeType, SizeType, SizeType) const { return true; }

	// siteNew2 is fringe in the environment
	SizeType getSubstituteSite(SizeType smax, SizeType emin, SizeType siteNew2) const
	{
		assert(siteNew2 >= emin);
		SizeType tmp = siteNew2 - emin + smax + 1;
		assert(tmp < linSize_);
		return tmp;
	}

	String label() const { return "LongRange"; }

	SizeType findReflection(SizeType site) const
	{
		return linSize_ - site - 1;
	}

	SizeType length(SizeType i) const
	{
		assert(i == 0);
		return linSize_;
	}

	SizeType translate(SizeType site, SizeType dir, SizeType amount) const
	{
		assert(dir == 0);

		site += amount;
		while (site >= linSize_)
			site -= linSize_;
		return site;
	}

	template 
	void write(Archive&, const unsigned int)
	{
		throw RuntimeError("LongRange::write(): unimplemented\n");
	}

private:

	void setEntangler(ComplexOrRealType value)
	{
		const SizeType n = matrix_.rows();
		for (SizeType i = 0; i < n; ++i)
			for (SizeType j = i + 1; j < n; ++j)
				matrix_(i, j) = value;
	}

	static void checkConnectors(const MatrixType& matrix, SizeType linSize)
	{
		PsimagLite::String str;
		if (matrix.rows() != matrix.cols())
			str = "LongRange: Connectors matrix isn't square\n";

		if (matrix.rows() % linSize != 0)
			str += "LongRange: Connectors matrix isn't divisible "
			       "by number of sites\n";

		if (hasDiagonal(matrix)) {
			str += "LongRange: Connectors matrix has non-zero "
			       "diagonal value(s)\n";
		}

		if (hasLowerTriangle(matrix)) {
			str += "LongRange: Connectors matrix has non-zero(es) "
			       "in lower triangle\n";
		}

		if (str.empty())
			return;
		throw RuntimeError(str);
	}

	static bool hasDiagonal(const MatrixType& matrix)
	{
		SizeType n = matrix.rows();
		if (n != matrix.cols())
			return true;
		for (SizeType i = 0; i < n; ++i) {
			if (PsimagLite::norm(matrix(i, i)) != 0)
				return true;
		}

		return false;
	}

	static bool hasLowerTriangle(const MatrixType& matrix)
	{
		for (SizeType i = 0; i < matrix.rows(); ++i) {
			for (SizeType j = 0; j < i; ++j) {
				if (PsimagLite::norm(matrix(i, j)) != 0)
					return true;
			}
		}

		return false;
	}

	SizeType linSize_;
	SizeType orbitals_;
	SizeType maxConnections_;
	MatrixType matrix_;
}; // class LongRange
} // namespace PsimagLite

/*@}*/
#endif // LADDER_H
PsimagLite-3.06/src/Geometry/Star.h000066400000000000000000000103751446452427400171660ustar00rootroot00000000000000/*
Copyright (c) 2014, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file Star.h
 *
 *  DOC NEEDED FIXME
 */
#ifndef GEOMETRY_STAR_H
#define GEOMETRY_STAR_H
#include "GeometryBase.h"

namespace PsimagLite
{

template 
class Star : public GeometryBase
{

public:

	enum { DIRECTION_S };

	static const SizeType CENTER = 1;

	Star() { }

	Star(SizeType linSize, InputType&)
	    : linSize_(linSize)
	{
	}

	virtual SizeType maxConnections() const { return linSize_ - 1; }

	virtual SizeType dirs() const { return 1; }

	SizeType handle(SizeType i, SizeType j) const
	{
		return (i < j) ? j - 1 : i - 1;
	}

	SizeType getVectorSize(SizeType dirId) const
	{
		if (dirId != DIRECTION_S)
			throw RuntimeError("Star must have direction 0\n");
		return linSize_ - 1;
	}

	bool connected(SizeType i1, SizeType i2) const
	{
		if (i1 == i2)
			return false;
		return (i1 == CENTER || i2 == CENTER);
	}

	// assumes i1 and i2 are connected
	SizeType calcDir(SizeType, SizeType) const { return DIRECTION_S; }

	bool fringe(SizeType i, SizeType, SizeType emin) const
	{
		return (i == emin);
	}

	// siteNew2 is fringe in the environment
	SizeType getSubstituteSite(SizeType, SizeType, SizeType siteNew2) const
	{
		return siteNew2;
	}

	String label() const { return "star"; }

	SizeType findReflection(SizeType) const
	{
		throw RuntimeError("findReflection\n");
	}

	SizeType length(SizeType i) const
	{
		assert(i == 0);
		return linSize_;
	}

	SizeType translate(SizeType, SizeType dir, SizeType) const
	{
		assert(dir == 0);

		throw RuntimeError("translate\n");
	}

private:

	SizeType linSize_;
}; // class Star
} // namespace PsimagLite

/*@}*/
#endif // GEOMETRY_STAR_H
PsimagLite-3.06/src/GetBraOrKet.h000066400000000000000000000053431446452427400165720ustar00rootroot00000000000000#ifndef GETBRAORKET_H
#define GETBRAORKET_H
#include "Vector.h"
#include 

namespace PsimagLite
{

class GetBraOrKet
{

public:

	enum class Kind { E,
		P,
		R }; // R means reserved for internal use

	typedef std::pair PairSizeType;

	GetBraOrKet(String braOrKet)
	    : isKet_(true)
	    , braOrKet_(braOrKet)
	    , kind_(Kind::E)
	    , pair_(0, 0)
	{
		const SizeType l = braOrKet.length();
		if (l < 2)
			err("GetBraOrKet " + braOrKet + "\n");
		const SizeType last = l - 1;
		if (braOrKet_[0] == '|' && braOrKet_[last] == '>' && l > 2)
			braOrKet_ = braOrKet.substr(1, l - 2);
		if (braOrKet_[0] == '<' && braOrKet_[last] == '|' && l > 2) {
			braOrKet_ = braOrKet.substr(1, l - 2);
			isKet_ = false;
		}

		getKind(braOrKet_);
	}

	bool isKet() const { return isKet_; }

	const String& toString() const { return braOrKet_; }

	bool isPvector() const { return (kind_ == Kind::P); }

	bool isRvector() const { return (kind_ == Kind::R); }

	SizeType levelIndex() const
	{
		checkIfPvector(false);
		return pair_.second;
	}

	SizeType sectorIndex() const
	{
		checkIfPvector(false);
		return pair_.first;
	}

	SizeType pIndex() const
	{
		checkIfPvector(true);
		return pair_.first;
	}

private:

	void checkIfPvector(bool b) const
	{
		bool isP = (kind_ == Kind::P || kind_ == Kind::R);
		if (isP == b)
			return;
		throw PsimagLite::RuntimeError(
		    "Internal ERROR: checkIfPpvector\n");
	}

	void getKind(String str)
	{
		if (str.length() < 2)
			err("GetBraOrKet:: " + str + "too short\n");

		if (str[0] == 'P') {
			kind_ = Kind::P;
			pair_.first = getNumberFrom(str, 1); // modifies str
		} else if (str == "gs") {
			kind_ = Kind::E;
			return;
		} else if (str == "time") { // legacy name
			kind_ = Kind::P;
			return;
		} else if (str[0] == 'Q') {
			kind_ = Kind::E;
			pair_.first = getNumberFrom(str, 1); // modifies str
		} else if (str[0] == 'R') {
			kind_ = Kind::R;
			pair_.first = getNumberFrom(str, 1); // modifies str
			return;
		}

		if (str.size() < 2)
			return;

		if (str[0] == 'X') {
			pair_.second = getNumberFrom(str, 1); // modifies str
		} else {
			err("A vector spec can only start with P, gs, X or Q " + str + "\n");
		}
	}

	static SizeType getNumberFrom(String& str, SizeType start)
	{
		String number("");
		SizeType i = start;
		for (; i < str.length(); ++i) {
			unsigned char x = str[i];
			if (x < 48 || x > 57)
				break;
			number += str[i];
		}

		if (number == "")
			RuntimeError("getNumberFrom: no number after character "
				     "location "
			    + ttos(start) + " for string " + str + "\n");

		str = str.substr(i, str.length() - i);

		return atoi(number.c_str());
	}

	bool isKet_;
	String braOrKet_;
	Kind kind_;
	PairSizeType pair_;
};
} // namespace PsimagLite
#endif // GETBRAORKET_H
PsimagLite-3.06/src/GslWrapper.h000066400000000000000000000155721446452427400165540ustar00rootroot00000000000000/*
Copyright (c) 2011-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file GslWrapper.h
 *
 *  Wrapper for GSL functions and types
 */

#ifndef GSL_WRAPPER_H_
#define GSL_WRAPPER_H_

#ifdef USE_GSL
#include 
#include 
#include 
#include 
#include 
#endif

#include "Vector.h"
#include 

namespace PsimagLite
{

#ifndef USE_GSL
class GslWrapper
{
public:

	typedef int DummyType;
	typedef DummyType gsl_integration_workspace;
	typedef double (*GslWrapperFunctionType)(double, void*);
	typedef struct {
		double val;
		double err;
	} gsl_sf_result;

	typedef void (*gsl_error_handler_t)(const char*, const char*, int, int);

	struct gsl_function {
		GslWrapperFunctionType function;
		void* params;
	};

	gsl_error_handler_t gsl_set_error_handler(gsl_error_handler_t) const
	{

		thereSnoGsl();
		gsl_error_handler_t* fx = new gsl_error_handler_t();

		return *fx;
	}

	gsl_integration_workspace*
	gsl_integration_workspace_alloc(SizeType) const
	{
		thereSnoGsl();
		int* x = new int;
		return x;
	}

	void gsl_integration_workspace_free(gsl_integration_workspace*) const
	{
		thereSnoGsl();
	}

	int gsl_integration_qag(const gsl_function*, double, double, double, double, size_t, int, gsl_integration_workspace*, double*, double*) const
	{
		thereSnoGsl();
		return 0;
	}

	int gsl_integration_qagiu(gsl_function*, double, double, double, size_t, gsl_integration_workspace*, double*, double*) const
	{
		thereSnoGsl();
		return 0;
	}

	int gsl_integration_qagp(const gsl_function*, double*, SizeType, double, double, SizeType, gsl_integration_workspace*, double*, double*) const
	{
		thereSnoGsl();
		return 0;
	}

	int gsl_integration_qagi(gsl_function*, double, double, size_t, gsl_integration_workspace*, double*, double*) const
	{
		thereSnoGsl();
		return 0;
	}

	void printError(int) const { thereSnoGsl(); }

	int gsl_sf_lngamma_complex_e(double, double, gsl_sf_result*, gsl_sf_result*) const
	{
		thereSnoGsl();
		return 0;
	}

	int gsl_sf_Ci_e(double, gsl_sf_result*)
	{
		thereSnoGsl();
		return 0;
	}

private:

	void thereSnoGsl() const
	{
		throw RuntimeError("You need to compile with the GSL\n");
	}

}; // class GslWrapper

#else

class GslWrapper
{
public:

	typedef ::gsl_integration_workspace gsl_integration_workspace;
	typedef ::gsl_function gsl_function;
	typedef ::gsl_sf_result gsl_sf_result;

	void printError(int status) const
	{
		std::cerr << "GslWrapper: error: " << gsl_strerror(status)
			  << "\n";
	}

	gsl_error_handler_t*
	gsl_set_error_handler(gsl_error_handler_t* new_handler) const
	{
		return ::gsl_set_error_handler(new_handler);
	}

	gsl_integration_workspace*
	gsl_integration_workspace_alloc(SizeType n) const
	{
		return ::gsl_integration_workspace_alloc(n);
	}

	void gsl_integration_workspace_free(gsl_integration_workspace* w) const
	{
		return ::gsl_integration_workspace_free(w);
	}

	int gsl_integration_qagi(gsl_function* f, double epsabs, double epsrel, size_t limit, gsl_integration_workspace* workspace, double* result, double* abserr) const
	{
		return ::gsl_integration_qagi(f, epsabs, epsrel, limit, workspace, result, abserr);
	}

	int gsl_integration_qagiu(gsl_function* f, double a, double epsabs, double epsrel, size_t limit, gsl_integration_workspace* workspace, double* result, double* abserr) const
	{
		return ::gsl_integration_qagiu(f, a, epsabs, epsrel, limit, workspace, result, abserr);
	}

	int gsl_integration_qagp(const gsl_function* f, double* pts, SizeType npts, double epsabs, double epsrel, SizeType limit, gsl_integration_workspace* workspace, double* result, double* abserr) const
	{
		return ::gsl_integration_qagp(f, pts, npts, epsabs, epsrel, limit, workspace, result, abserr);
	}

	int gsl_integration_qag(const gsl_function* f, double a, double b, double epsabs, double epsrel, size_t limit, int key, gsl_integration_workspace* workspace, double* result, double* abserr) const
	{
		return ::gsl_integration_qag(f, a, b, epsabs, epsrel, limit, key, workspace, result, abserr);
	}

	int gsl_sf_lngamma_complex_e(double zr, double zi, gsl_sf_result* lnr, gsl_sf_result* arg) const
	{
		return ::gsl_sf_lngamma_complex_e(zr, zi, lnr, arg);
	}

	int gsl_sf_Ci_e(double x, gsl_sf_result* result) const
	{
		return ::gsl_sf_Ci_e(x, result);
	}

}; // class GslWrapper

#endif

} // namespace PsimagLite

/*@}*/
#endif // GSL_WRAPPER_H_
PsimagLite-3.06/src/InputCheckBase.h000066400000000000000000000065601446452427400173130ustar00rootroot00000000000000/*
Copyright (c) 2009-2020, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 2.]
[see file AUTHORS for authorsL]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup DMRG */
/*@{*/

/*! \file InputCheckBase.h
 *
 *  InputChecking functions
 */
#ifndef PSI_INPUTCHECK_BASE_H
#define PSI_INPUTCHECK_BASE_H
#include 
#include 

namespace PsimagLite
{

class InputCheckBase
{

	typedef PsimagLite::Vector::Type VectorStringType;

public:

	PsimagLite::String import() const { return ""; }

	bool check(const PsimagLite::String& label,
	    const PsimagLite::Vector::Type& vec,
	    SizeType line) const
	{
		return false;
	}

	void check(const PsimagLite::String& label,
	    const PsimagLite::String& val,
	    SizeType)
	{
		return;
	}

	bool checkSimpleLabel(const PsimagLite::String& label,
	    SizeType line) const
	{
		return false;
	}

}; // class InputCheckBase
} // namespace PsimagLite

/*@}*/
#endif
PsimagLite-3.06/src/InputNg.h000066400000000000000000000653641446452427400160560ustar00rootroot00000000000000/*
Copyright (c) 2012, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************


*/

/** \ingroup PsimagLite */
/*@{*/

/*! \file InputNg.h
 *
 *
 */

#ifndef INPUT_NG_H
#define INPUT_NG_H

#include "Ainur/Ainur.h"
#include "Map.h"
#include "Matrix.h"
#include "PsiBase64.h"
#include "Vector.h"
#include "loki/TypeTraits.h"
#include 
#include 
#include 
#include 
#include 
#include 

namespace PsimagLite
{

template 
class InputNg
{

	class MyCompare
	{

		enum { FIRST,
			SECOND };

		typedef std::pair PairType;

	public:

		bool operator()(const String& x1, const String& x2) const
		{
			PairType p1 = mysplit(x1);
			PairType p2 = mysplit(x2);
			if (p1.second == 0 && p2.second == 0)
				return (x1 < x2);
			if (p1.second == 0)
				return true;
			if (p2.second == 0)
				return false;
			if (p1.first != p2.first)
				return (x1 < x2);
			return (p1.second < p2.second);
		}

	private:

		PairType mysplit(const String& x) const
		{
			SizeType mode = FIRST;
			String xfirst = "";
			String xsecond = "";
			for (SizeType i = 0; i < x.length(); i++) {
				if (x[i] == '@') {
					mode = SECOND;
					continue;
				}
				if (mode == FIRST)
					xfirst += x[i];
				else
					xsecond += x[i];
			}
			if (xsecond == "")
				return PairType(xfirst, 0);
			return PairType(xfirst, atoi(xsecond.c_str()));
		}
	};

	typedef MyCompare MyCompareType;

	typedef typename Map::Type MapStrStrType;
	typedef typename Map::Type, MyCompareType>::Type
	    MapStrVecType;

public:

	class Writeable
	{

		enum {
			WHITESPACE,
			ENDOFLINE,
			EQUALSIGN,
			ALPHA_CHAR,
			NUMERIC_CHAR,
			COMMENT
		};

		enum {
			IN_LABEL,
			IN_VALUE_OR_LABEL,
			IN_VALUE_TEXT,
			IN_VALUE_NUMERIC,
			IN_COMMENT
		};

	public:

		typedef Vector::Type VectorStringType;

		Writeable(const InputCheckType& inputCheck, String data)
		    : data_(data)
		    , line_(0)
		    , state_(IN_LABEL)
		    , numericVector_(0)
		    , lastLabel_("")
		    , file_("")
		    , inputCheck_(inputCheck)
		    , verbose_(false)
		    , ainurMode_(false)
		{
			internal();
		}

		Writeable(const String& file, const InputCheckType& inputCheck)
		    : data_("")
		    , line_(0)
		    , state_(IN_LABEL)
		    , numericVector_(0)
		    , lastLabel_("")
		    , file_(file)
		    , inputCheck_(inputCheck)
		    , verbose_(false)
		    , ainurMode_(false)
		{
			internal(file);
		}

		void set(MapStrStrType& mapStrStr, MapStrVecType& mapStrVec, Vector::Type& labelsForRemoval) const
		{
			if (ainurMode_)
				return;
			mapStrStr = mapStrStr_;
			mapStrVec = mapStrVec_,
			labelsForRemoval = labelsForRemoval_;
		}

		const String& filename() const { return file_; }

		const String& data() const { return data_; }

		bool ainurMode() const { return ainurMode_; }

		const InputCheckType& inputCheck() const { return inputCheck_; }

		static void readFile(String& data, String file)
		{
			std::ifstream fin(file.c_str());
			if (!fin || !fin.good() || fin.bad()) {
				String s(__FILE__);
				s += " Cannot open file " + file + "\n";
				throw RuntimeError(s.c_str());
			}

			char c = 0;
			while (!fin.eof()) {
				fin.get(c);
				data += c;
			}

			fin.close();
		}

	private:

		void internal(PsimagLite::String file)
		{
			readFile(data_, file);

			internal();
		}

		void internal()
		{
			if (data_.size() > 2 && data_[0] == '#' && data_[1] == '#')
				ainurMode_ = true;

			changeAndParse();

			if (verbose_ && !ainurMode_) {
				std::cout << "START\n";
				printMap(mapStrStr_, "StrStr");
				std::cout << "END\nSTART\n";
				printMap(mapStrVec_, "StrVec");
				std::cout << "END\n";
			}
		}

		void changeAndParse()
		{
			changeDataIfNeeded();

			if (ainurMode_)
				return;

			parseInternal();
		}

		void changeDataIfNeeded()
		{
			VectorStringType vlines;
			splitIntoLines(vlines);
			data_ = "";
			const SizeType n = vlines.size();
			for (SizeType i = 0; i < n; ++i) {
				const String& thisline = vlines[i];
				data_ += replaceLine(thisline);
			}
		}

		void splitIntoLines(VectorStringType& vlines) const
		{
			String buffer("");
			const SizeType n = data_.length();
			for (SizeType i = 0; i < n; ++i) {
				if (data_[i] == '\n') {
					vlines.push_back(buffer);
					buffer = "";
				} else {
					buffer += data_[i];
				}
			}

			vlines.push_back(buffer);
		}

		// !A$iB a b c d ...
		// gets replaced by
		// A0B=a;
		// A1B=b;
		// A2B=c;
		// ...
		// The semicolon is used only in ainurMode
		String replaceLine(String line) const
		{
			if (line[0] != '!')
				return line + "\n";

			const SizeType n = line.length();
			SizeType ind = 1;
			String a;
			for (; ind < n; ++ind) {
				if (line[ind] == '$')
					break;
				a += line[ind];
			}

			++ind;
			if (ind >= n)
				throw RuntimeError(
				    "replaceLine: syntax error near " + line + "\n");

			if (line[ind] != 'i')
				throw RuntimeError(
				    "replaceLine: syntax error near " + line + "\n");

			++ind;
			String b;
			for (; ind < n; ++ind) {
				if (line[ind] == ' ' || line[ind] == '\t')
					break;
				b += line[ind];
			}

			++ind;
			String rest;
			for (; ind < n; ++ind)
				rest += line[ind];
			if (rest == "")
				throw RuntimeError(
				    "replaceLine: syntax error near " + line + "\n");

			VectorStringType tokens;
			split(tokens, rest, " ");
			const SizeType m = tokens.size();

			String newline;
			for (SizeType i = 0; i < m; ++i) {
				newline += a + ttos(i) + b + "=" + tokens[i];
				if (ainurMode_)
					newline += ";";
				newline += "\n";
			}

			return newline;
		}

		void parseInternal()
		{
			String buffer = "";
			for (SizeType i = 0; i < data_.length(); i++) {
				SizeType type = findTypeOf(data_.at(i));
				if (state_ == IN_COMMENT && type != ENDOFLINE)
					continue;
				switch (type) {
				case ENDOFLINE:
					line_++;
					if (state_ == IN_COMMENT) {
						state_ = IN_LABEL;
						break;
					}
					if (buffer == "")
						break;
					saveBuffer(buffer, ENDOFLINE);
					buffer = "";
					break;
				case WHITESPACE:
					if (buffer == "" || state_ == IN_COMMENT)
						break;
					saveBuffer(buffer, WHITESPACE);
					buffer = "";
					break;
				case EQUALSIGN:
					if (buffer == "" || state_ == IN_COMMENT)
						break;

					// support = sign in value text
					if (state_ == IN_VALUE_TEXT) {
						buffer += data_.at(i);
						break;
					}

					saveBuffer(buffer, EQUALSIGN);
					buffer = "";
					break;
				case COMMENT:
					state_ = IN_COMMENT;
					break;
				default:
					if (state_ == IN_VALUE_OR_LABEL) {
						if (type == ALPHA_CHAR) {
							checkNumbers();
							numericVector_.clear();
							state_ = IN_LABEL;
						} else {
							state_ = IN_VALUE_NUMERIC;
						}
					}

					buffer += data_.at(i);
					break;
				}
			}
			if (numericVector_.size() > 0)
				checkNumbers();
		}

		void saveBuffer(const String& buffer, SizeType whatchar)
		{
			String s(__FILE__);
			String adjLabel = "";
			switch (state_) {
			case IN_LABEL:
				if (verbose_)
					std::cout << "Read label=" << buffer
						  << "\n";
				lastLabel_ = buffer;
				inputCheck_.checkSimpleLabel(lastLabel_, line_);
				if (whatchar == EQUALSIGN)
					state_ = IN_VALUE_TEXT;
				else
					state_ = IN_VALUE_NUMERIC;
				break;
			case IN_VALUE_OR_LABEL:
				std::cerr << "Line=" << line_ << "\n";
				s += "Error while buffer=" + buffer;
				s += String(" and current line=") + String("\n");
				break;
			case IN_VALUE_TEXT:
				if (verbose_)
					std::cout
					    << "Read text value=" << buffer
					    << "\n";
				adjLabel = adjLabelForDuplicates(lastLabel_,
				    mapStrStr_);
				mapStrStr_[adjLabel] = buffer;
				state_ = IN_LABEL;
				inputCheck_.check(adjLabel, buffer, line_);
				break;
			case IN_VALUE_NUMERIC:
				if (verbose_)
					std::cout
					    << "Read numeric value=" << buffer
					    << "\n";
				numericVector_.push_back(buffer);
				state_ = IN_VALUE_OR_LABEL;
				break;
			}
		}

		SizeType findTypeOf(char c) const
		{
			if (c == '\n')
				return ENDOFLINE;
			if (c == ' ' || c == '\t')
				return WHITESPACE;
			if (c == '=')
				return EQUALSIGN;
			if (c >= 48 && c <= 58)
				return NUMERIC_CHAR;
			if (c == '.' || c == '+' || c == '-')
				return NUMERIC_CHAR;
			if (c == '(' || c == ')' || c == ',')
				return NUMERIC_CHAR;
			if (c == '#')
				return COMMENT;
			return ALPHA_CHAR;
		}

		void checkNumbers()
		{
			if (numericVector_.size() == 1) {
				String s(__FILE__);
				s += " use equal sign instead of space in "
				     "line "
				    + ttos(line_) + "\n";
				throw RuntimeError(s.c_str());
			}

			String s(__FILE__);
			if (numericVector_.size() == 0) {
				std::cerr << "Line=" << line_ << "\n";
				throw RuntimeError(s.c_str());
			}
			SizeType adjExpected = atoi(numericVector_[0].c_str());

			if (!inputCheck_.check(lastLabel_, numericVector_, line_) && numericVector_.size() != adjExpected + 1) {
				std::cout << " Number of numbers to follow is "
					     "wrong, expected ";
				std::cout << adjExpected << " got ";
				std::cout << (numericVector_.size() - 1)
					  << "\n";
				std::cerr << "Line=" << line_ << "\n";
				throw RuntimeError(s.c_str());
			}

			String adjLabel = adjLabelForDuplicates(lastLabel_, mapStrVec_);
			mapStrVec_[adjLabel] = numericVector_;
		}

		template 
		String adjLabelForDuplicates(const String& label,
		    SomeMapType& mymap)
		{
			String rootLabel = findRootLabel(label);
			int x = findLastOccurrence(rootLabel, mymap);
			if (x < 0)
				return label;
			labelsForRemoval_.push_back(rootLabel);
			x++;
			String newlabel = rootLabel + "@" + ttos(x);
			if (verbose_)
				std::cerr << "NEWLABEL=*" << newlabel << "*\n";
			return newlabel;
		}

		template 
		int findLastOccurrence(const String& root1, SomeMapType& mymap)
		{
			int x = -1;
			for (typename SomeMapType::iterator it = mymap.begin();
			     it != mymap.end();
			     ++it) {
				String root2 = findRootLabel(it->first);
				if (root1 == root2)
					x++;
			}
			return x;
		}

		template 
		typename EnableIf::True, void>::Type
		printMap(MapType& mp, const String& label)
		{
			//			typedef typename
			// MapType::key_type KeyType; 			typedef
			// typename MapType::mapped_type MappedType;
			std::cout << label << "\n";
			typename MapType::iterator it;
			for (it = mp.begin(); it != mp.end(); ++it) {
				std::cout << it->first << " " << it->second
					  << "\n";
			}
		}

		String data_;
		SizeType line_;
		SizeType state_;
		Vector::Type numericVector_;
		String lastLabel_;
		String file_;
		InputCheckType inputCheck_;
		bool verbose_;
		bool ainurMode_;
		typename Map::Type mapStrStr_;
		typename Map::Type, MyCompareType>::Type
		    mapStrVec_;
		Vector::Type labelsForRemoval_;
	}; // class Writeable

	class Readable
	{

	public:

		typedef typename Map::Type
		    MapStringStringType;
		typedef typename MapStringStringType::iterator
		    MapStringIteratorType;
		typedef typename Map::Type, MyCompareType>::Type::iterator
		    MapStringVectorIteratorType;

		Readable(const Writeable& inputWriteable)
		    : file_(inputWriteable.filename())
		    , data_(inputWriteable.data())
		    , ainur_(0)
		    , dummy_("")
		{
			inputWriteable.set(mapStrStr_, mapStrVec_, labelsForRemoval_);
			if (inputWriteable.ainurMode()) {
				if (extensionOf(file_) == "inp") {
					String w("WARNING: Ainur file but inp "
						 "file extension\n");
					std::cout << AnsiColor::magenta << w
						  << AnsiColor::reset;
					std::cerr << AnsiColor::magenta << w
						  << AnsiColor::reset;
				}

				ainur_ = new Ainur(
				    inputWriteable.inputCheck().import() + data_);
				ainur_->setMap(mapStrStr_);
			}
		}

		~Readable()
		{
			delete ainur_;
			ainur_ = 0;
		}

		void rewind() { }

		bool isAinur() const { return (ainur_ != nullptr); }

		double versionAinur() const { return 2.5; }

		double version() const { return (ainur_) ? 3. : 2.; }

		void printUnused(std::ostream& os) const
		{
			if (!ainur_)
				return;
			ainur_->printUnused(os);
		}

		const PsimagLite::String& data() const { return data_; }

		String& prefix()
		{
			return (ainur_) ? ainur_->prefix() : dummy_;
		}

		String prefix() const
		{
			return (ainur_) ? ainur_->prefix() : "";
		}

		void readline(String& val, const String& label, bool clean = true, bool forceRemoval = false)
		{
			if (ainur_) {
				String label2 = label;
				SizeType last = label2.length();
				if (last > 0) {
					--last;
					if (label2[last] == '=')
						label2 = label.substr(0, last);
				}

				return ainur_->readValue(val, label2);
			}

			String label2 = label2label(label);
			MapStringIteratorType it = findFirstValueForLabel(label2, mapStrStr_);
			if (it == mapStrStr_.end())
				throwWithMessage(label, label2);

			val = it->second.c_str();

			if (clean)
				cleanLabelsIfNeeded(label2, mapStrStr_, it, forceRemoval);
		}

		template 
		typename EnableIf::isFloat,
		    void>::Type
		readline(FloatingType& val, const String& label)
		{
			if (ainur_) {
				String label2 = label;
				SizeType last = label2.length();
				if (last > 0) {
					--last;
					if (label2[last] == '=')
						label2 = label.substr(0, last);
				}

				return ainur_->readValue(val, label2);
			}

			String label2 = label2label(label);
			MapStringIteratorType it = findFirstValueForLabel(label2, mapStrStr_);
			if (it == mapStrStr_.end())
				throwWithMessage(label, label2);

			val = atof(it->second.c_str());

			cleanLabelsIfNeeded(label2, mapStrStr_, it);
		}

		void readline(long int& val, const String& label)
		{
			if (ainur_) {
				String label2 = label;
				SizeType last = label2.length();
				if (last > 0) {
					--last;
					if (label2[last] == '=')
						label2 = label.substr(0, last);
				}

				return ainur_->readValue(val, label2);
			}

			String label2 = label2label(label);
			MapStringIteratorType it = findFirstValueForLabel(label2, mapStrStr_);
			if (it == mapStrStr_.end())
				throwWithMessage(label, label2);

			val = atoi(it->second.c_str());

			cleanLabelsIfNeeded(label2, mapStrStr_, it);
		}

		void readline(SizeType& val, const String& label)
		{
			if (ainur_) {
				String label2 = label;
				SizeType last = label2.length();
				if (last > 0) {
					--last;
					if (label2[last] == '=')
						label2 = label.substr(0, last);
				}

				return ainur_->readValue(val, label2);
			}

			String label2 = label2label(label);
			MapStringIteratorType it = findFirstValueForLabel(label2, mapStrStr_);
			if (it == mapStrStr_.end())
				throwWithMessage(label, label2);

			val = atoi(it->second.c_str());

			cleanLabelsIfNeeded(label2, mapStrStr_, it);
		}

		void readline(int& val, const String& label)
		{
			if (ainur_) {
				String label2 = label;
				SizeType last = label2.length();
				if (last > 0) {
					--last;
					if (label2[last] == '=')
						label2 = label.substr(0, last);
				}

				return ainur_->readValue(val, label2);
			}

			String label2 = label2label(label);
			MapStringIteratorType it = findFirstValueForLabel(label2, mapStrStr_);
			if (it == mapStrStr_.end())
				throwWithMessage(label, label2);

			val = atoi(it->second.c_str());

			cleanLabelsIfNeeded(label2, mapStrStr_, it);
		}

		void read(SizeType& val, const String& label)
		{
			if (ainur_)
				err("Read not supported. Label= " + label + "\n");

			String label2 = label2label(label);

			MapStringIteratorType it = findFirstValueForLabel(label2, mapStrStr_);
			if (it == mapStrStr_.end())
				throwWithMessage(label, label2);

			val = atoi(it->second.c_str());

			cleanLabelsIfNeeded(label2, mapStrStr_, it);
		}

		template 
		typename EnableIf::True,
		    void>::Type
		read(VectorLikeType& val, const String& label)
		{
			if (ainur_)
				return ainur_->readValue(val, label);

			String label2 = label2label(label);
			typedef typename VectorLikeType::value_type NumericType;
			MapStringVectorIteratorType it = findFirstValueForLabel(label2, mapStrVec_);
			if (it == mapStrVec_.end())
				throwWithMessage(label, label2);

			SizeType len = it->second.size();
			assert(len > 1);
			val.resize(len - 1);
			for (SizeType i = 0; i < len - 1; i++) {
				val[i] = stringToComplexOrReal(
				    it->second[i + 1].c_str());
			}
			cleanLabelsIfNeeded(label2, mapStrVec_, it);
		}

		template 
		typename EnableIf::isFloat,
		    void>::Type
		read(Matrix& m, const String& label)
		{
			if (ainur_)
				return ainur_->readValue(m, label);

			String label2 = label2label(label);

			MapStringVectorIteratorType it = findFirstValueForLabel(label2, mapStrVec_);
			if (it == mapStrVec_.end())
				throwWithMessage(label, label2);

			bool b1 = (it->second.size() < 2);
			bool b2 = (atoi(it->second[0].c_str()) <= 0);
			bool b3 = (atoi(it->second[1].c_str()) <= 0);
			if (b1 || b2 || b3) {
				String s(__FILE__);
				s += " reading a matrix: " + it->second[0];
				s += " " + it->second[1] + "\n";
				throw RuntimeError(s.c_str());
			}

			SizeType nrow = SizeType(atoi(it->second[0].c_str()));
			SizeType ncol = SizeType(atoi(it->second[1].c_str()));
			m.resize(nrow, ncol);
			if (it->second.size() < 2 + nrow * ncol) {
				String s(__FILE__);
				s += " reading a matrix: \n";
				throw RuntimeError(s.c_str());
			}
			SizeType k = 2;
			for (SizeType i = 0; i < m.rows(); i++)
				for (SizeType j = 0; j < m.cols(); j++)
					m(i, j) = atof(it->second[k++].c_str());

			cleanLabelsIfNeeded(label2, mapStrVec_, it);
		}

		template 
		typename EnableIf::isFloat,
		    void>::Type
		read(Matrix>& m, const String& label)
		{
			if (ainur_)
				return ainur_->readValue(m, label);

			String label2 = label2label(label);

			MapStringVectorIteratorType it = findFirstValueForLabel(label2, mapStrVec_);
			if (it == mapStrVec_.end())
				throwWithMessage(label, label2);

			if (it->second.size() < 2 || atoi(it->second[0].c_str()) <= 0 || atoi(it->second[1].c_str()) <= 0) {
				String s(__FILE__);
				s += " reading a matrix: \n";
				throw RuntimeError(s.c_str());
			}

			SizeType nrow = SizeType(atoi(it->second[0].c_str()));
			SizeType ncol = SizeType(atoi(it->second[1].c_str()));
			m.resize(nrow, ncol);
			if (it->second.size() < 2 + nrow * ncol) {
				String s(__FILE__);
				s += " reading a matrix: \n";
				throw RuntimeError(s.c_str());
			}
			SizeType k = 2;
			for (SizeType i = 0; i < m.rows(); i++) {
				for (SizeType j = 0; j < m.cols(); j++) {
					IstringStream is(it->second[k++]);
					is >> m(i, j);
				}
			}
			cleanLabelsIfNeeded(label2, mapStrVec_, it);
		}

		template 
		typename EnableIf::True, void>::Type
		read(MapLikeType& val, const String& label)
		{
			if (ainur_)
				err("Read not supported. Label= " + label + "\n");

			String label2 = label2label(label);

			typedef typename Map::Type::iterator
			    MyIteratorType;
			for (MyIteratorType it = mapStrStr_.begin();
			     it != mapStrStr_.end();
			     ++it) {
				String mystr = it->first;
				long unsigned int it0 = mystr.find(label2);
				if (it0 == String::npos)
					continue;
				String::iterator it1 = find(mystr.begin(), mystr.end(), '[');
				if (it1 == mystr.end())
					continue;
				String::iterator it2 = find(mystr.begin(), mystr.end(), ']');
				if (it2 == mystr.end()) {
					String str("Malformed ");
					str += mystr + " entry\n";
					throw RuntimeError(str);
				}
				String mystr2 = mystr;
				mystr2.erase(0, label2.length() + 1);
				mystr2.erase(mystr2.length() - 1, 1);
				val[mystr2] = atof(it->second.c_str());
			}
		}

		void read(Matrix& m, const String& label)
		{
			if (ainur_)
				return ainur_->readValue(m, label);

			throw RuntimeError("InputNg: Matrix not "
					   "supported in POD inputs\n");
		}

		MapStrStrType map() const { return mapStrStr_; }

		const String& filename() const { return file_; }

	private:

		template 
		void cleanLabelsIfNeeded(const String& label,
		    SomeMapType& mymap,
		    typename SomeMapType::iterator& it,
		    bool forceRemoval = false)
		{
			Vector::Type::iterator it2 = find(labelsForRemoval_.begin(),
			    labelsForRemoval_.end(),
			    label);
			if (it2 != labelsForRemoval_.end() || forceRemoval)
				mymap.erase(it);
		}

		String label2label(const String& label)
		{
			SizeType len = label.length();
			if (len == 0) {
				String s(__FILE__);
				s += " readline: label cannot be null\n";
				throw RuntimeError(s.c_str());
			}
			if (label.at(len - 1) == '=')
				len--;
			return label.substr(0, len);
		}

		template 
		typename SomeMapType::iterator
		findFirstValueForLabel(const String& label, SomeMapType& mymap)
		{
			for (typename SomeMapType::iterator it = mymap.begin();
			     it != mymap.end();
			     ++it) {
				String root2 = findRootLabel(it->first);
				if (label == root2) {
					return it;
				}
			}
			return mymap.end();
		}

		template 
		typename EnableIf::True,
		    ComplexOrRealType>::Type
		stringToComplexOrReal(const String& s) const
		{
			typedef typename Real::Type RealType;

			if (s[0] != '(') {
				return stringToReal(s.c_str());
			}

			String buffer("");
			SizeType start = 0;
			for (SizeType i = 1; i < s.length(); ++i) {
				start = i;
				if (s[i] == ',')
					break;
				buffer += s[i];
			}

			RealType r = stringToReal(buffer);

			start++;
			buffer = "";
			for (SizeType i = start; i < s.length(); ++i) {
				if (s[i] == ')')
					break;
				buffer += s[i];
			}

			RealType img = stringToReal(buffer);

			return ComplexOrRealType(r, img);
		}

		template 
		typename EnableIf<
		    !IsComplexNumber::True && Loki::TypeTraits::isArith,
		    typename Real::Type>::Type
		stringToComplexOrReal(const String& s) const
		{
			return static_cast<
			    typename Real::Type>(
			    stringToReal(s));
		}

		template 
		typename EnableIf::True,
		    String>::Type
		stringToComplexOrReal(const String& s) const
		{
			return s;
		}

		double stringToReal(const String& s) const
		{
			for (SizeType i = 0; i < s.length(); ++i) {
				char c = s[i];
				bool b1 = (c < 48 || c > 57);
				bool b2 = (c != '.' && c != '-' && c != '+' && c != 'e' && c != 'E');
				if (b1 && b2) {
					String str = s + " is not a real number\n";
					str += "Suggestion: Add -DUSE_COMPLEX "
					       "to your Makefile.\n";
					throw RuntimeError(str);
				}
			}

			return atof(s.c_str());
		}

		void throwWithMessage(const String& label,
		    const String& label2 = "")
		{
			String s("Message issued by: ");
			s += String(__FILE__) + "\n";
			s += "ATTENTION: ERROR MESSAGE, PLEASE READ: ";
			s += " The (probably) mandatory label: " + label;
			if (label2.length() > 0 && label2 != label)
				s += " (a.k.a. " + label2 + ")";
			s += " was not found in the input file.\n";
			throw RuntimeError(s.c_str());
		}

		static String extensionOf(String s)
		{
			const SizeType l = s.length();
			String buffer;
			bool flag = false;
			for (SizeType i = 0; i < l; ++i) {
				const SizeType j = l - i - 1;
				if (s[j] == '.') {
					flag = true;
					break;
				}

				buffer += s[j];
			}

			if (!flag)
				return "";

			String buffer2 = buffer;
			const SizeType l2 = buffer.length();
			for (SizeType i = 0; i < l2; ++i) {
				const SizeType j = l2 - i - 1;
				buffer2[j] = buffer[i];
			}

			return buffer2;
		}

		// serializr start class InputNgReadable
		// serializr normal file_
		String file_;
		String data_;
		// serializr normal mapStrStr_
		MapStringStringType mapStrStr_;
		// serializr normal mapStrVec_
		typename Map::Type, MyCompareType>::Type
		    mapStrVec_;
		// serializr normal labelsForRemoval_
		Vector::Type labelsForRemoval_;
		Ainur* ainur_;
		String dummy_;
	}; // class Readable

	static String findRootLabel(const String& label)
	{
		String buffer = "";
		SizeType len = label.length();
		for (SizeType i = 0; i < len; i++) {
			if (label.at(i) == '@')
				break;
			buffer += label.at(i);
		}
		return buffer;
	}

}; // InputNg

class InputEmptyCheck
{
};

} // namespace PsimagLite

/*@}*/

#endif // INPUT_NG_H
PsimagLite-3.06/src/Integrator.h000066400000000000000000000044301446452427400165730ustar00rootroot00000000000000#ifndef PSI_INTEGRATOR_H
#define PSI_INTEGRATOR_H

#include "GslWrapper.h"

namespace PsimagLite
{

template 
class Integrator
{

public:

	typedef GslWrapper GslWrapperType;
	typedef typename FunctionType::RealType RealType;
	typedef typename PsimagLite::Vector::Type VectorRealType;

	enum IntegrationEnum { INTEG_QAG,
		INTEG_QAGP };

	Integrator(FunctionType& function, RealType epsabs = 1e-9, RealType epsrel = 1e-9, SizeType limit = 1000000)
	    : epsabs_(epsabs)
	    , epsrel_(epsrel)
	    , limit_(limit)
	    , result_(0)
	    , abserr_(0)
	    , workspace_(
		  gslWrapper_.gsl_integration_workspace_alloc(limit_ + 2))
	{
		f_.function = &FunctionType::function;

		f_.params = &function.params();
	}

	~Integrator()
	{
		gslWrapper_.gsl_integration_workspace_free(workspace_);
	}

	RealType operator()(VectorRealType& pts,
	    IntegrationEnum integ = INTEG_QAG,
	    int key = 4)
	{
		switch (integ) {
		default:
			return qag(pts, key);
		case INTEG_QAGP:
			return qagp(pts);
		}
	}

	RealType toInfinity(RealType a, IntegrationEnum integ = INTEG_QAG, int key = 4)
	{
		int status = gslWrapper_.gsl_integration_qagiu(
		    &f_, a, epsabs_, epsrel_, limit_, workspace_, &result_, &abserr_);
		if (status)
			gslWrapper_.printError(status);

		return result_;
	}

	RealType operator()()
	{
		int status = gslWrapper_.gsl_integration_qagi(
		    &f_, epsabs_, epsrel_, limit_, workspace_, &result_, &abserr_);

		if (status)
			gslWrapper_.printError(status);

		return result_;
	}

private:

	RealType qagp(VectorRealType& pts)
	{
		int status = gslWrapper_.gsl_integration_qagp(
		    &f_, &(pts[0]), pts.size(), epsabs_, epsrel_, limit_, workspace_, &result_, &abserr_);

		if (status)
			gslWrapper_.printError(status);

		return result_;
	}

	RealType qag(const VectorRealType& pts, int key)
	{
		int status = gslWrapper_.gsl_integration_qag(
		    &f_, pts[0], pts[1], epsabs_, epsrel_, limit_, key, workspace_, &result_, &abserr_);

		if (status)
			gslWrapper_.printError(status);

		return result_;
	}

	GslWrapperType gslWrapper_;
	RealType epsabs_;
	RealType epsrel_;
	SizeType limit_;
	RealType result_;
	RealType abserr_;
	GslWrapperType::gsl_integration_workspace* workspace_;
	GslWrapperType::gsl_function f_;
};
} // namespace PsimagLite
#endif // PSI_INTEGRATOR_H
PsimagLite-3.06/src/InterNode.h000066400000000000000000000003031446452427400163370ustar00rootroot00000000000000#ifndef INTER_NODE_H
#define INTER_NODE_H
#include "Concurrency.h"
#include "Vector.h"

#ifdef USE_MPI
#include "InterNodeMpi.h"
#else
#include "InterNodeSerial.h"
#endif

#endif // INTER_NODE_H
PsimagLite-3.06/src/InterNodeMpi.h000066400000000000000000000037021446452427400170130ustar00rootroot00000000000000#ifndef INTER_NODE_MPI_H
#define INTER_NODE_MPI_H
#include "LoadBalancerMpi.h"
#include "Mpi.h"
#include "TypeToString.h"
#include "Vector.h"
#include 
#include 
#include 
#include 

namespace PsimagLite
{

template 
class InterNode
{

public:

	typedef LoadBalancerMpi::VectorSizeType VectorSizeType;

	InterNode(MPI::CommType comm)
	    : comm_(comm)
	    , mpiSize_(MPI::commSize(comm_))
	    , mpiRank_(MPI::commRank(comm_))
	{
	}

	SizeType size() const { return mpiSize_; }

	String name() const { return "mpi"; }

	// no weights, no balancer ==> create weights, set all weigths to 1,
	// delegate
	template 
	void parallelFor(SizeType start, SizeType end, const SomeLambdaType& lambda)
	{
		LoadBalancerType* loadBalancer = new LoadBalancerType(end - start, mpiSize_);
		parallelFor(start, end, lambda, *loadBalancer);
		delete loadBalancer;
		loadBalancer = 0;
	}

	// weights, no balancer ==> create balancer with weights ==> delegate
	template 
	void parallelFor(SizeType start, SizeType end, const SomeLambdaType& lambda, const VectorSizeType& weights)
	{
		LoadBalancerType* loadBalancer = new LoadBalancerType(weights.size(), mpiSize_);
		loadBalancer->setWeights(weights);
		parallelFor(start, end, lambda, *loadBalancer);
		delete loadBalancer;
		loadBalancer = 0;
	}

	template 
	void parallelFor(SizeType start, SizeType end, const SomeLambdaType& lambda, const LoadBalancerType& loadBalancer)
	{
		SizeType blockSize = loadBalancer.blockSize(mpiRank_);

		for (SizeType p = 0; p < blockSize; ++p) {
			SizeType taskNumber = loadBalancer.taskNumber(mpiRank_, p);
			if (taskNumber + start >= end)
				break;
			lambda(taskNumber + start, mpiRank_);
		}

		MPI::barrier(comm_);
	}

private:

	MPI::CommType comm_;
	SizeType mpiSize_;
	SizeType mpiRank_;
};
} // namespace PsimagLite
#endif // INTER_NODE_MPI_H
PsimagLite-3.06/src/InterNodeSerial.h000066400000000000000000000010111446452427400174740ustar00rootroot00000000000000#ifndef INTER_NODE_SERIAL_H
#define INTER_NODE_SERIAL_H
#include "Mpi.h"
#include "Vector.h"

namespace PsimagLite
{

template 
class InterNode
{

public:

	InterNode(MPI::CommType) { }

	template 
	void parallelFor(SizeType start, SizeType end, const SomeLambdaType& lambda)
	{
		for (SizeType i = start; i < end; ++i)
			lambda(i, 0);
	}

	SizeType size() const { return 1; }

	String name() const { return "serial"; }
};
} // namespace PsimagLite
#endif // INTER_NODE_SERIAL_H
PsimagLite-3.06/src/Io/000077500000000000000000000000001446452427400146525ustar00rootroot00000000000000PsimagLite-3.06/src/Io/IoNg.h000066400000000000000000000203361446452427400156630ustar00rootroot00000000000000/*
Copyright (c) 2009-2018, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 2.]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/

/** \ingroup PsimagLite */
/*@{*/

/*! \file IoNg.h
 *
 *  This class handles Input/Output for PsimagLite
 */

#ifndef PSI_IO_NG_H
#define PSI_IO_NG_H

#include "AllocatorCpu.h"
#include "IoNgSerializer.h"
#include "Map.h"
#include "Matrix.h"
#include "Stack.h"
#include "Vector.h"
#include 
#include 
#include 

namespace PsimagLite
{

/* PSIDOC IsRootUnDelegated
Root-undelegated types are one of the following.
\begin{lstlisting}
PSIDOCCOPY IsRootUnDelegatedCode
\end{lstlisting}
Root-undelegateds are always at least partially written to by \code{IoNg},
and, if needed, parts of it are delegated.
For example, all native types are written by \code{IoNg} directly into a single
dataset. \code{std::complex} where \code{T} is a native type is written
directly by doubling the size of the array into a single dataset.
*/
/* PSIDOC_CODE_START IsRootUnDelegatedCode */
template 
struct IsRootUnDelegated {
	enum {
		True = Loki::TypeTraits::isArith || IsVectorLike::True || IsStackLike::True || IsPairLike::True || std::is_enum::value || IsEnumClass::value || IsStringLike::True
	};
};
/* PSIDOC_CODE_END */

class IoNg
{

public:

	/*
		H5F_ACC_TRUNC - Truncate file, if it already exists,
		erasing all data previously stored in the file.
		H5F_ACC_EXCL - Fail if file already exists. H5F_ACC_TRUNC
		and H5F_ACC_EXCL are mutually exclusive
		H5F_ACC_RDONLY - Open file as read-only, if it already exists,
	   and fail, otherwise H5F_ACC_RDWR - Open file for read/write, if it
	   already exists, and fail, otherwise
	*/
	enum OpenMode { ACC_TRUNC,
		ACC_EXCL,
		ACC_RDONLY,
		ACC_RDW };

	static void dontPrintDebug() { IoNgSerializer::dontPrintDebug(); }

	class Out
	{

	public:

		typedef IoNgSerializer Serializer;
		typedef std::vector VectorStringType;

		Out(const String& filename, OpenMode mode)
		    : ioNgSerializer_(filename, modeToH5(mode))
		{
		}

		void flush() { ioNgSerializer_.flush(); }

		const String& filename() const
		{
			return ioNgSerializer_.filename();
		}

		void open(String filename, OpenMode mode)
		{
			ioNgSerializer_.open(filename, modeToH5(mode));
		}

		void close() { ioNgSerializer_.close(); }

		void createGroup(String groupName)
		{
			ioNgSerializer_.createGroup(groupName);
		}

		template 
		void writeVectorEntry(T x, PsimagLite::String str, SizeType counter)
		{
			if (counter == 0)
				createGroup(str);

			ioNgSerializer_.write(str + "/" + ttos(counter), x);
			ioNgSerializer_.write(
			    str + "/Size", counter + 1, (counter == 0) ? IoNgSerializer::NO_OVERWRITE : IoNgSerializer::ALLOW_OVERWRITE);
		}

		template 
		void write(std::stack& what, String name2, IoNgSerializer::WriteMode mode = IoNgSerializer::NO_OVERWRITE, typename EnableIf::True, int*>::Type = 0)
		{
			ioNgSerializer_.write(name2, what, mode);
		}

		template 
		void write(const T& what, String name2, IoNgSerializer::WriteMode mode = IoNgSerializer::NO_OVERWRITE, typename EnableIf::True, int*>::Type = 0)
		{
			ioNgSerializer_.write(name2, what, mode);
		}

		template 
		void write(const T& what, String name2, typename EnableIf::True, int*>::Type = 0)
		{
			what.write(name2, ioNgSerializer_);
		}

		template 
		void write(const T& what, String name2, IoNgSerializer::WriteMode mode, typename EnableIf::True, int*>::Type = 0)
		{
			what.write(name2, ioNgSerializer_, mode);
		}

		template 
		void overwrite(const T& what, String name2, typename EnableIf::True, int*>::Type = 0)
		{
			ioNgSerializer_.overwrite(name2, what);
		}

		template 
		void overwrite(const T& what, String name2, typename EnableIf::True, int*>::Type = 0)
		{
			what.overwrite(name2, ioNgSerializer_);
		}

		IoNgSerializer& serializer() { return ioNgSerializer_; }

	private:

		Out(const Out&);

		Out& operator=(const Out&);

		static unsigned int modeToH5(OpenMode mode)
		{
			switch (mode) {
			case ACC_TRUNC:
				return H5F_ACC_TRUNC;
			case ACC_EXCL:
				return H5F_ACC_EXCL;
			case ACC_RDONLY:
				return H5F_ACC_RDONLY;
			case ACC_RDW:
				return H5F_ACC_RDWR;
			}

			throw RuntimeError("IoNg:: wrong open mode\n");
		}

		IoNgSerializer ioNgSerializer_;
	};

	class In
	{

	public:

		typedef int long LongIntegerType;
		typedef unsigned int long LongSizeType;

		In(String filename)
		    : ioNgSerializer_(filename, H5F_ACC_RDONLY)
		{
		}

		const String& filename() const
		{
			return ioNgSerializer_.filename();
		}

		void open(String filename)
		{
			ioNgSerializer_.open(filename, H5F_ACC_RDONLY);
		}

		void close() { ioNgSerializer_.close(); }

		template 
		void readLastVectorEntry(SomeType& x, String s)
		{
			int total = 0;
			ioNgSerializer_.read(total, s + "/Size");

			if (total <= 0)
				throw RuntimeError(
				    "Error reading last instance of " + s + "\n");

			ioNgSerializer_.read(x, s + "/" + ttos(--total));
		}

		template 
		void read(T& what, String name, typename EnableIf::True, int*>::Type = 0)
		{
			ioNgSerializer_.read(what, name);
		}

		template 
		void read(T& what, String name, typename EnableIf::True, int*>::Type = 0)
		{
			what.read(name, ioNgSerializer_);
		}

		IoNgSerializer& serializer() { return ioNgSerializer_; }

	private:

		In(const In&);

		In& operator=(const In&);

		IoNgSerializer ioNgSerializer_;
	};
}; // class IoNg

template <>
struct IsInputLike {
	enum { True = true };
};

template <>
struct IsOutputLike {
	enum { True = true };
};

} // namespace PsimagLite

/*@}*/
#endif
PsimagLite-3.06/src/Io/IoNgSerializer.h000066400000000000000000000552451446452427400177240ustar00rootroot00000000000000#ifndef IONGSERIALIZER_H
#define IONGSERIALIZER_H
#include "../Complex.h"
#include "../TypeToString.h"
#include "../Vector.h"
#include "TypeToH5.h"
#include 
#include 
#include 

namespace PsimagLite
{

class IoNgSerializer
{

	typedef std::vector VectorOfBoolInternalType;

	static const unsigned char CANARY_VALUE = 170;

public:

	/*
		H5F_ACC_TRUNC - Truncate file, if it already exists,
		erasing all data previously stored in the file.
		H5F_ACC_EXCL - Fail if file already exists. H5F_ACC_TRUNC
		and H5F_ACC_EXCL are mutually exclusive
		H5F_ACC_RDONLY - Open file as read-only, if it already exists,
	   and fail, otherwise H5F_ACC_RDWR - Open file for read/write, if it
	   already exists, and fail, otherwise
	*/

	enum WriteMode { NO_OVERWRITE,
		ALLOW_OVERWRITE };

	IoNgSerializer(String filename, unsigned int mode)
	    : hdf5file_(0)
	    , filename_(filename)
	    , mode_(mode)
	{
#ifdef NDEBUG
		dontPrintDebug();
#endif

		try {
			hdf5file_ = new H5::H5File(filename, mode);
		} catch (H5::Exception& e) {
			delete hdf5file_;
			hdf5file_ = 0;
			throw e;
		}

		if (mode == H5F_ACC_TRUNC) {
			try {
				createGroup("");
			} catch (H5::Exception& e) {
				filename_ = "";
				delete hdf5file_;
				hdf5file_ = 0;
				throw e;
			}
		}

		if (mode == H5F_ACC_RDONLY) {
			try {
				readCanary();
			} catch (H5::Exception& e) {
				filename_ = "";
				delete hdf5file_;
				hdf5file_ = 0;
				throw e;
			}
		}
	}

	~IoNgSerializer()
	{
		if (hdf5file_ && mode_ != H5F_ACC_RDONLY)
			writeCanary();

		filename_ = "";
		delete hdf5file_;
		hdf5file_ = 0;
	}

	static void dontPrintDebug() { H5::Exception::dontPrint(); }

	void open(String filename, unsigned int mode)
	{
		if (hdf5file_)
			throw RuntimeError(
			    "IoNgSerializer::open(): object already open\n");

		filename_ = filename;
		hdf5file_ = new H5::H5File(filename, mode);
		if (hdf5file_ && mode_ != H5F_ACC_RDONLY)
			writeCanary();
	}

	void close()
	{
		if (hdf5file_ && mode_ != H5F_ACC_RDONLY)
			writeCanary();

		hdf5file_->close();
		delete hdf5file_;
		hdf5file_ = 0;
		filename_ = "";
	}

	void flush()
	{
		if (hdf5file_ && mode_ != H5F_ACC_RDONLY)
			writeCanary();

		hdf5file_->flush(H5F_SCOPE_GLOBAL);
	}

	const String& filename() const { return filename_; }

	void createGroup(String group)
	{
		hdf5file_->createGroup("Def/" + group);
	}

	bool doesGroupExist(String groupName)
	{
		groupName = "Def/" + groupName;

		try {
			H5::Group group = hdf5file_->openGroup(groupName.c_str());
			group.close();
		} catch (...) {
			return false;
		}

		return true;
	}

	/* write functions START */

	template 
	bool write(String name2, const T& what, WriteMode allowOverwrite = NO_OVERWRITE, typename EnableIf::isArith || std::is_enum::value, int*>::Type = 0)
	{
		String name = "Def/" + name2;
		const void* ptr = static_cast(&what);
		hsize_t dims[1];
		dims[0] = 1;

		if (allowOverwrite)
			return overwrite(name, ptr, dims, 1);
		else
			internalWrite(name, ptr, dims, 1);
		return true;
	}

	void write(String name2, String what, WriteMode allowOverwrite = NO_OVERWRITE)
	{
		overwriteNotSupported(allowOverwrite);
		String name = "Def/" + name2;
		hsize_t dims[1];
		dims[0] = what.length();
		void* ptr = static_cast(&what[0]);
		internalWrite(name, ptr, dims, 1);
	}

	void write(String name2, bool b, WriteMode allowOverwrite = NO_OVERWRITE)
	{
		String name = "Def/" + name2;

		unsigned char tmp[1];
		tmp[0] = (b) ? 1 : 0;
		const void* ptr = static_cast(tmp);

		hsize_t dims[1];
		dims[0] = 1;

		if (allowOverwrite == ALLOW_OVERWRITE)
			overwrite(name, ptr, dims, 1);
		else
			internalWrite(name, ptr, dims, 1);
	}

	template 
	void write(String name2, const std::pair& what, WriteMode allowOverwrite = NO_OVERWRITE, typename EnableIf::isArith && Loki::TypeTraits::isArith, int*>::Type = 0)
	{
		if (allowOverwrite != ALLOW_OVERWRITE)
			createGroup(name2);
		write(name2 + "/0", what.first, allowOverwrite);
		write(name2 + "/1", what.second, allowOverwrite);
	}

	template 
	void write(String name2, const std::pair& what, WriteMode allowOverwrite = NO_OVERWRITE, typename EnableIf::isArith && !Loki::TypeTraits::isArith, int*>::Type = 0)
	{
		overwriteNotSupported(allowOverwrite);
		createGroup(name2);
		write(name2 + "/0", what.first);
		what.second.write(name2 + "/1", *this);
	}

	// Note: THIS WILL EMPTY THE STACK OBJECT!
	template 
	void write(String name, std::stack& what, WriteMode allowOverwrite = NO_OVERWRITE, typename EnableIf::Type>::isArith, int*>::Type = 0)
	{
		overwriteNotSupported(allowOverwrite);
		createGroup(name);
		write(name + "/Size", what.size());
		SizeType i = 0;
		while (what.size() > 0) {
			const T& t = what.top();
			t.write(name + "/" + ttos(i++), *this);
			what.pop();
		}
	}

	void write(String name, const std::vector& what, WriteMode allowOverwrite = NO_OVERWRITE)
	{
		VectorOfBoolInternalType converted = convertFromBoolean(what);
		write(name, converted, allowOverwrite);
	}

	template 
	void
	write(String name2, const std::vector& what, WriteMode allowOverwrite = NO_OVERWRITE, typename EnableIf::isArith, int*>::Type = 0)
	{
		if (what.size() == 0)
			return;
		String name = "Def/" + name2;
		hsize_t dims[1];
		dims[0] = what.size();
		assert(0 < what.size());
		const void* ptr = static_cast(&what[0]);

		if (Loki::TypeTraits::isFloat)
			writeComplexOrReal(name2, 'R');
		if (allowOverwrite == ALLOW_OVERWRITE)
			overwrite(name, ptr, dims, 1);
		else
			internalWrite(name, ptr, dims, 1);
	}

	template 
	void
	write(String name2, const std::vector>& what, WriteMode allowOverwrite = NO_OVERWRITE, typename EnableIf::isArith, int*>::Type = 0)
	{
		if (what.size() == 0)
			return;

		assert(0 < what.size());
		const void* ptr = static_cast(&what[0]);
		String name = "Def/" + name2;
		hsize_t dims[1];
		dims[0] = 2 * what.size();

		writeComplexOrReal(name2, 'C');
		if (allowOverwrite == ALLOW_OVERWRITE)
			overwrite(name2, ptr, dims, 1);
		else
			internalWrite(name, ptr, dims, 1);
	}

	template 
	void write(
	    String name2,
	    const std::vector>& what,
	    WriteMode allowOverwrite = NO_OVERWRITE,
	    typename EnableIf::Type>::isArith,
		int*>::Type
	    = 0)
	{
		SizeType n = what.size();
		if (allowOverwrite != ALLOW_OVERWRITE)
			createGroup(name2);
		write(name2 + "/Size", n, allowOverwrite);
		for (SizeType i = 0; i < n; ++i)
			write(name2 + "/" + typeToString(i), what[i], allowOverwrite);
	}

	template 
	void write(String name2, const std::vector>& what, WriteMode allowOverwrite = NO_OVERWRITE, typename EnableIf::isArith && Loki::TypeTraits::isArith, int*>::Type = 0)
	{
		overwriteNotSupported(allowOverwrite);
		SizeType n = what.size();
		createGroup(name2);
		write(name2 + "/Size", n);
		for (SizeType i = 0; i < n; ++i)
			write(name2 + "/" + typeToString(i), what[i]);
	}

	template 
	void write(String name2, const std::vector& what, typename EnableIf::Type>::isArith && !IsPairLike::True && !IsEnumClass::value, int*>::Type = 0)
	{
		SizeType n = what.size();
		createGroup(name2);
		write(name2 + "/Size", n);
		for (SizeType i = 0; i < n; ++i)
			what[i].write(name2 + "/" + typeToString(i), *this);
	}

	template 
	void write(String name2, const std::vector& what, WriteMode allowOverwrite, typename EnableIf::Type>::isArith && !IsPairLike::True && !IsEnumClass::value, int*>::Type = 0)
	{
		SizeType n = what.size();
		if (allowOverwrite != ALLOW_OVERWRITE)
			createGroup(name2);
		write(name2 + "/Size", n, allowOverwrite);
		for (SizeType i = 0; i < n; ++i)
			what[i].write(name2 + "/" + typeToString(i), *this, allowOverwrite);
	}

	template 
	void write(String name2, const std::vector& what, WriteMode allowOverwrite = NO_OVERWRITE, typename EnableIf::value, int*>::Type = 0)
	{
		overwriteNotSupported(allowOverwrite);
		SizeType n = what.size();
		createGroup(name2);
		write(name2 + "/Size", n);
		for (SizeType i = 0; i < n; ++i)
			write(name2 + "/" + typeToString(i), what[i]);
	}

	template 
	void overwrite(String name2, const std::vector& what, typename EnableIf::Type>::isArith && !IsPairLike::True, int*>::Type = 0)
	{
		SizeType n = what.size();
		SizeType oldN = 0;
		read(oldN, name2 + "/Size");
		SizeType min = std::min(oldN, n);
		write(name2 + "/Size", n, ALLOW_OVERWRITE);
		for (SizeType i = 0; i < min; ++i)
			what[i].overwrite(name2 + "/" + typeToString(i), *this);

		if (n <= oldN)
			return;

		for (SizeType i = min; i < n; ++i) {
			try {
				what[i].write(name2 + "/" + typeToString(i),
				    *this);
			} catch (...) {
				what[i].overwrite(name2 + "/" + typeToString(i),
				    *this);
			}
		}
	}

	template 
	void write(String name2, const std::vector& what, WriteMode allowOverwrite = NO_OVERWRITE, typename EnableIf::Type>::isArith && IsPairLike::True, int*>::Type = 0)
	{
		overwriteNotSupported(allowOverwrite);
		SizeType n = what.size();
		createGroup(name2);
		write(name2 + "/Size", n);
		for (SizeType i = 0; i < n; ++i)
			write(name2 + "/" + typeToString(i), what[i]);
	}

	template 
	void write(String name2, const std::vector& what, WriteMode allowOverwrite = NO_OVERWRITE, typename EnableIf::Type>::isArith, int*>::Type = 0)
	{
		overwriteNotSupported(allowOverwrite);
		SizeType n = what.size();
		createGroup(name2);
		write(name2 + "/Size", n);
		for (SizeType i = 0; i < n; ++i)
			what[i]->write(name2 + "/" + typeToString(i), *this);
	}

	/* write functions END */

	// read functions START

	template 
	void read(SomeType& value, String name, typename EnableIf::isArith && !std::is_enum::value, int*>::Type = 0)
	{
		void* ptr = static_cast(&value);
		H5::DataSet* dataset = new H5::DataSet(hdf5file_->openDataSet("Def/" + name));
		dataset->read(ptr, typeToH5());
		delete dataset;
	}

	void read(String& what, String name) { readInternal(what, name); }

	void read(bool& value, String name)
	{
		unsigned char tmp[1];
		tmp[0] = 0;
		void* ptr = static_cast(tmp);
		H5::DataSet* dataset = new H5::DataSet(hdf5file_->openDataSet("Def/" + name));
		dataset->read(ptr, typeToH5());
		delete dataset;
		value = (tmp[0] & 1);
	}

	template 
	void read(std::pair& what, String name, typename EnableIf::isArith && Loki::TypeTraits::isArith, int*>::Type = 0)
	{
		read(what.first, name + "/0");
		read(what.second, name + "/1");
	}

	template 
	void read(std::pair& what, String name, typename EnableIf::isArith && !Loki::TypeTraits::isArith, int*>::Type = 0)
	{
		read(what.first, name + "/0");
		what.second.read(name + "/1", *this);
	}

	void read(std::vector& what, String name)
	{
		VectorOfBoolInternalType original;
		read(original, name);
		convertToBoolean(what, original);
	}

	template 
	void read(SomeType& value, String name, typename EnableIf::value || IsEnumClass::value, int*>::Type = 0)
	{
		SizeType x = 0;
		read(x, name);
		value = static_cast(x);
	}

	template 
	void
	read(std::vector& what, String name, typename EnableIf::isArith, int*>::Type = 0)
	{
		readInternal(what, name);
	}

	template 
	void
	read(std::vector>& what, String name, typename EnableIf::isArith, int*>::Type = 0)
	{
		readInternal(what, name);
	}

	template 
	void read(std::vector>& what, String name, typename EnableIf::isArith && Loki::TypeTraits::isArith, int*>::Type = 0)
	{
		SizeType size = 0;
		read(size, name + "/Size");
		what.resize(size);
		for (SizeType i = 0; i < size; ++i)
			read(what[i], name + "/" + typeToString(i));
	}

	template 
	void read(std::vector& what, String name, typename EnableIf::Type>::isArith && !IsPairLike::True && !IsEnumClass::value, int*>::Type = 0)
	{
		SizeType size = 0;
		read(size, name + "/Size");
		what.resize(size);
		for (SizeType i = 0; i < size; ++i)
			what[i].read(name + "/" + ttos(i), *this);
	}

	template 
	void read(std::vector& what, String name, typename EnableIf::Type>::isArith && IsPairLike::True, int*>::Type = 0)
	{
		SizeType size = 0;
		read(size, name + "/Size");
		what.resize(size);
		for (SizeType i = 0; i < size; ++i)
			read(what[i], name + "/" + ttos(i));
	}

	template 
	void read(std::vector& what, String name, typename EnableIf::value, int*>::Type = 0)
	{
		SizeType size = 0;
		read(size, name + "/Size");
		what.resize(size);
		for (SizeType i = 0; i < size; ++i)
			read(what[i], name + "/" + ttos(i));
	}

	template 
	void read(std::vector>& what, String name)
	{
		SizeType size = 0;
		read(size, name + "/Size");
		what.resize(size);
		for (SizeType i = 0; i < size; ++i)
			read(what[i], name + "/" + ttos(i));
	}

	template 
	void read(std::stack& what, String name)
	{
		SizeType x = 0;
		read(x, name + "/Size");
		for (SizeType i = 0; i < x; ++i) {
			T t;
			t.read(name + "/" + ttos(x - i - 1), *this);
			what.push(t);
		}
	}

	static void unitTest(std::vector& x)
	{
		VectorOfBoolInternalType y = convertFromBoolean(x);
		std::cout << "convertFromBoolean\n";
		std::cout << "Input ";
		for (SizeType i = 0; i < x.size(); ++i)
			std::cout << x[i] << " ";
		std::cout << "\nOutput: ";
		for (SizeType i = 0; i < y.size(); ++i)
			std::cout << static_cast(y[i])
				  << " ";
		std::cout << "\n\nconvertToBoolean\n";
		x.clear();
		convertToBoolean(x, y);
		std::cout << "Output ";
		for (SizeType i = 0; i < x.size(); ++i)
			std::cout << x[i] << " ";
		std::cout << "\n";
	}

	// read functions END

private:

	IoNgSerializer(const IoNgSerializer&);

	IoNgSerializer& operator=(const IoNgSerializer&);

	// We're reading from disk, so we go from type in disk to type in
	// destination The type of destination is SomeVectorType The underlying
	// type of destination is SomeVectorType::value_type Therefore, we have
	// underlying type in disk and underlying type in destination Let's call
	// floating the set {double, float} underlying type ut_disk in disk is
	// in {floating, complex, other} underlying type ut_dest in destination
	// is also in {floating, complex, other} if ut_disk == ut_dest all is
	// good if ut_disk != ut_dest we throw unless ut_disk == floating and
	// ut_dest is std::complex so that we can go from floating to
	// complex

	enum class ReadEnum { FLOATING,
		COMPLEX,
		OTHER };

	template 
	void readInternal(SomeVectorType& what, String name)
	{
		typedef typename Real::Type
		    UnderlyingType;

		H5::DataSet* dataset = new H5::DataSet(hdf5file_->openDataSet("Def/" + name));
		const H5::DataSpace& dspace = dataset->getSpace();
		const int ndims = dspace.getSimpleExtentNdims();
		if (ndims != 1)
			throw RuntimeError("IoNgSerializer: problem reading "
					   "vector ndims != 1\n");

		hsize_t* dims = new hsize_t[ndims];
		dspace.getSimpleExtentDims(dims);

		const hsize_t n = dims[0];
		if (n == 0)
			throw RuntimeError("IoNgSerializer: problem reading "
					   "vector dims[0] == 0\n");

		const ReadEnum readEnumOnDisk = getReadEnumOnDisk(name);
		static const ReadEnum readEnumDest = getReadEnumDestination<
		    typename SomeVectorType::value_type>();

		if (readEnumOnDisk == readEnumDest) {
			SizeType complexSize = (readEnumDest == ReadEnum::COMPLEX) ? getHalfSize(n)
										   : n;
			what.resize(complexSize, 0);
			void* ptr = static_cast(&(what[0]));
			dataset->read(ptr, typeToH5());
			delete[] dims;
			delete dataset;
			return;
		}

		// only other case is from real --> complex
		if (readEnumOnDisk == ReadEnum::FLOATING && readEnumDest == ReadEnum::COMPLEX) {
			// this type is complex; but what's on disk is real
			typename Vector::Type temporary(
			    dims[0]);
			void* ptr2 = static_cast(&(temporary[0]));
			dataset->read(ptr2, typeToH5());
			what.resize(dims[0]);
			for (SizeType i = 0; i < dims[0]; ++i)
				what[i] = temporary[i]; // real to complex
			delete[] dims;
			delete dataset;
			return;
		}

		throw RuntimeError("IoNgSerializer: problem reading vector\n");
	}

	void overwriteNotSupported(WriteMode mode)
	{
		if (mode == NO_OVERWRITE)
			return;
		throw RuntimeError("Overwrite not supported for this type\n");
	}

	template 
	bool overwrite(String name, const void* ptr, hsize_t dims[], SizeType ndims)
	{
		try {
			hdf5file_->unlink(name);
		} catch (...) {
			std::cerr << "Cannot unlink " << name << "\n";
		}

		return internalWrite(name, ptr, dims, ndims);
	}

	template 
	bool internalWrite(String name, const void* ptr, hsize_t dims[], SizeType ndims)
	{
		H5::DataSpace* dataspace = new H5::DataSpace(ndims, dims); // create new dspace
		H5::DSetCreatPropList
		    dsCreatPlist; // What properties here? FIXME
		H5::DataSet* dataset = nullptr;
		try {
			dataset = new H5::DataSet(
			    hdf5file_->createDataSet(name, typeToH5(), *dataspace, dsCreatPlist));
		} catch (H5::Exception& e) {
			std::cerr << "H5 Exception createDataSet starts "
				     "<-------------\n";
			std::cerr << e.getDetailMsg() << "\n";
			std::cerr << "H5 Exception createDataSet ends   "
				     "<-------------\n";
			return false;
		}

		dataset->write(ptr, typeToH5());
		delete dataset;
		delete dataspace;
		return true;
	}

	void writeCanary()
	{
		hsize_t dims[1];
		dims[0] = 1;
		static const String name = "/Def/Canary";
		H5::DataSpace* dataspace = new H5::DataSpace(1, dims); // create new dspace
		H5::DSetCreatPropList
		    dsCreatPlist; // What properties here? FIXME
		H5::DataSet* dataset = 0;

		try {
			dataset = new H5::DataSet(hdf5file_->openDataSet(name));
		} catch (H5::Exception&) {
			dataset = new H5::DataSet(hdf5file_->createDataSet(
			    name, typeToH5(), *dataspace, dsCreatPlist));
		}

		unsigned char c = CANARY_VALUE;
		dataset->write(&c, typeToH5());
		delete dataset;
		delete dataspace;
	}

	void readCanary()
	{
		static const String name = "/Def/Canary";

		H5::DataSet* dataset = new H5::DataSet(hdf5file_->openDataSet(name));
		const H5::DataSpace& dspace = dataset->getSpace();
		const int ndims = dspace.getSimpleExtentNdims();
		if (ndims != 1)
			throw RuntimeError("IoNgSerializer: problem reading "
					   "vector (ndims)\n");

		hsize_t* dims = new hsize_t[ndims];
		dspace.getSimpleExtentDims(dims);

		if (dims[0] == 0)
			throw RuntimeError("IoNgSerializer: problem reading "
					   "vector (dims)\n");

		unsigned char c = 0;
		void* ptr = static_cast(&c);
		dataset->read(ptr, typeToH5());
		delete[] dims;
		delete dataset;

		if (c != CANARY_VALUE)
			throw RuntimeError("File " + filename_ + " is not valid (dead canary)\n");
	}

	static VectorOfBoolInternalType
	convertFromBoolean(const std::vector& src)
	{
		typedef VectorOfBoolInternalType::value_type ValueType;
		SizeType total = src.size();

		if (total == 0)
			return VectorOfBoolInternalType(booleanEncodedSize_, 0);

		SizeType bytesNeeded = total / 8;
		bytesNeeded += 5;

		VectorOfBoolInternalType c(bytesNeeded, 0);
		encodeBooleanSize(c, total);
		SizeType blockSize = sizeof(ValueType);

		ValueType mask = 1;
		SizeType j = booleanEncodedStart_;
		SizeType bytes = 0;
		for (SizeType i = 0; i < total; ++i) {
			assert(j < c.size());
			assert(mask > 0);
			if (src[i])
				c[j] |= mask;
			mask <<= 1;
			if (i > 0 && ((i + 1) % 8 == 0))
				++bytes;
			if (bytes == blockSize) {
				bytes = 0;
				++j;
				mask = 1;
			}
		}

		return c;
	}

	static void convertToBoolean(std::vector& dest,
	    const VectorOfBoolInternalType& x)
	{
		typedef VectorOfBoolInternalType::value_type ValueType;
		SizeType numberOfBits = sizeof(ValueType) * 8 * x.size();
		SizeType blockSize = sizeof(ValueType);

		SizeType encodedSize = decodeBooleanSize(x);
		assert(encodedSize <= numberOfBits);

		numberOfBits = encodedSize;

		dest.resize(numberOfBits);

		ValueType mask = 1;
		SizeType j = booleanEncodedStart_;
		SizeType bytes = 0;
		for (SizeType i = 0; i < numberOfBits; ++i) {
			assert(j < x.size());
			assert(mask > 0);
			dest[i] = (x[j] & mask);
			mask <<= 1;
			if (i > 0 && ((i + 1) % 8 == 0))
				++bytes;
			if (bytes == blockSize) {
				bytes = 0;
				++j;
				mask = 1;
			}
		}
	}

	static void encodeBooleanSize(VectorOfBoolInternalType& x,
	    SizeType total)
	{
		static short int byteSize = 256;
		assert(x.size() >= booleanEncodedSize_);
		SizeType tmp = total;
		std::fill(x.begin(), x.begin() + booleanEncodedSize_, 0);
		for (SizeType i = 0; i < booleanEncodedSize_; ++i) {
			x[i] = (tmp % byteSize);
			tmp >>= 8;
			if (tmp == 0)
				break;
		}
	}

	static SizeType decodeBooleanSize(const VectorOfBoolInternalType& x)
	{
		static short int byteSize = 256;
		assert(x.size() >= booleanEncodedSize_);
		SizeType tmp = 0;
		SizeType level = 1;
		for (SizeType i = 0; i < booleanEncodedSize_; ++i) {
			tmp += x[i] * level;
			level *= byteSize;
		}

		return tmp;
	}

	static hsize_t getHalfSize(hsize_t x)
	{
		if (x & 1)
			throw RuntimeError(
			    "FATAL: Complex vector with uneven fp size\n");

		return x / 2;
	}

	void writeComplexOrReal(String name2, char content)
	{
		String nameComplexOrReal = name2 + "ComplexOrReal";
		write(nameComplexOrReal, content);
	}

	ReadEnum getReadEnumOnDisk(String name2)
	{
		const String nameComplexOrReal = name2 + "ComplexOrReal";
		char tmp;
		try {
			read(tmp, nameComplexOrReal);
		} catch (...) {
			return ReadEnum::OTHER;
		}

		return (tmp == 'C') ? ReadEnum::COMPLEX : ReadEnum::FLOATING;
	}

	template 
	ReadEnum getReadEnumDestination()
	{
		if (IsComplexNumber::True)
			return ReadEnum::COMPLEX;
		return (Loki::TypeTraits::isFloat) ? ReadEnum::FLOATING
						      : ReadEnum::OTHER;
	}

	H5::H5File* hdf5file_;
	String filename_;
	unsigned int mode_;
	static const SizeType booleanEncodedSize_ = 4;
	static const SizeType booleanEncodedStart_ = 4;
};
} // namespace PsimagLite
#endif // IONGSERIALIZER_H
PsimagLite-3.06/src/Io/IoSelector.h000066400000000000000000000005171446452427400170760ustar00rootroot00000000000000#ifndef IOSELECTOR_H
#define IOSELECTOR_H

#include "IoSerializerStub.h"

#ifdef USE_IO_SIMPLE
#include "IoSimple.h"
#else
#include "IoNg.h"
#endif

namespace PsimagLite
{

#ifdef USE_IO_SIMPLE
typedef PsimagLite::IoSimple IoSelector;
#else
typedef PsimagLite::IoNg IoSelector;
#endif
} // namespace PsimagLite

#endif // IOSELECTOR_H
PsimagLite-3.06/src/Io/IoSerializerEmpty.h000066400000000000000000000033041446452427400204430ustar00rootroot00000000000000#ifndef IO_SERIALIZER_EMPTY_H
#define IO_SERIALIZER_EMPTY_H
#include "../Complex.h"
#include "../TypeToString.h"
#include "../Vector.h"
#include 
#include 

namespace PsimagLite
{

class IoSerializerEmpty
{

	typedef std::vector VectorOfBoolInternalType;

public:

	enum WriteMode { NO_OVERWRITE,
		ALLOW_OVERWRITE };

	IoSerializerEmpty(String, unsigned int) { errorPrint("ctor"); }

	void open(String, unsigned int) { errorPrint("open"); }

	void close() { errorPrint("close"); }

	void flush() { errorPrint("flush"); }

	String filename() const
	{
		errorPrint("filename");
		return "";
	}

	void createGroup(String) { errorPrint("createGroup"); }

	bool doesGroupExist(String)
	{
		errorPrint("doesGroupExist");
		return false;
	}

	/* write functions START */

	template 
	void write(String, const T&, WriteMode = NO_OVERWRITE)
	{
		errorPrint("write");
	}

	// Note: THIS WILL EMPTY THE STACK OBJECT!
	template 
	void write(String, std::stack&, WriteMode = NO_OVERWRITE, typename EnableIf::Type>::isArith, int*>::Type = 0)
	{
		errorPrint("write");
	}

	template 
	void read(T&, String) { errorPrint("read"); }

	static void unitTest(std::vector&) { errorPrint("unitTest"); }

	// read functions END

private:

	IoSerializerEmpty(const IoSerializerEmpty&);

	IoSerializerEmpty& operator=(const IoSerializerEmpty&);

	static void errorPrint(String fname)
	{
		throw RuntimeError(
		    "FATAL: You called IoSerializer::" + fname + " but you compiled with USE_IO_SIMPLE." + " Please delete USE_IO_SIMPLE from Makefile and" + " enable HDF5 support.\n");
	}
};
} // namespace PsimagLite
#endif // IO_SERIALIZER_EMPTY_H
PsimagLite-3.06/src/Io/IoSerializerStub.h000066400000000000000000000004721446452427400202650ustar00rootroot00000000000000#ifndef IOSERIALIZERSTUB_H
#define IOSERIALIZERSTUB_H

#ifndef USE_IO_SIMPLE

#include "IoNgSerializer.h"
namespace PsimagLite
{

typedef IoNgSerializer IoSerializer;

}

#else

#include "IoSerializerEmpty.h"

namespace PsimagLite
{

typedef IoSerializerEmpty IoSerializer;

}

#endif
#endif // IOSERIALIZERSTUB_H
PsimagLite-3.06/src/Io/IoSimple.h000066400000000000000000000252031446452427400165460ustar00rootroot00000000000000/*
Copyright (c) 2009-2018, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 2.]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/

/** \ingroup PsimagLite */
/*@{*/

/*! \file IoSimple.h
 *
 *  This class handles Input/Output in a simple way
 */

#ifndef IOSIMPLE_HEADER_H
#define IOSIMPLE_HEADER_H

#include "Concurrency.h"
#include "Map.h"
#include "Matrix.h"
#include "Stack.h"
#include 
#include 
#include 
#include 

namespace PsimagLite
{
//! IoSimple class handles Input/Output (IO) for the Dmrg++ program
class IoSimple
{

	template 
	struct PrintWithEqualSign {
		enum {
			True = Loki::TypeTraits::isArith || std::is_enum::value || IsComplexNumber::True
		};
	};

public:

	class Out
	{

	public:

		Out()
		    : rank_(0)
		    , fout_(0)
		{
		}

		Out(std::ostream& os)
		    : rank_(0)
		    , filename_("OSTREAM")
		{
			fout_ = (std::ofstream*)&os;
		}

		Out(const String& fn)
		    : rank_(Concurrency::rank())
		    , filename_(fn)
		    , fout_(0)
		{
			if (rank_ != 0)
				return;
			if (!fout_)
				fout_ = new std::ofstream;
#ifdef PSI_PUBSETBUF
			fout_->rdbuf()->pubsetbuf(0, 0);
#endif
			fout_->open(fn.c_str());
			if (!(*fout_) || !fout_->good())
				throw RuntimeError(
				    "Out: error while opening file!\n");
		}

		~Out()
		{
			if (rank_ != 0)
				return;
			if (filename_ == "OSTREAM" || !fout_)
				return;
			fout_->close();
			delete fout_;
		}

		bool ng() const { return false; }

		const String& filename() const { return filename_; }

		void open(String const& fn, std::ios_base::openmode mode)
		{
			if (rank_ != 0)
				return;
			if (filename_ == "OSTREAM")
				throw RuntimeError("open: not possible\n");
			filename_ = fn;
			if (!fout_)
				fout_ = new std::ofstream;
#ifdef PSI_PUBSETBUF
			fout_->rdbuf()->pubsetbuf(0, 0);
#endif
			fout_->open(fn.c_str(), mode);
			if (!(*fout_) || !fout_->good())
				throw RuntimeError(
				    "Out: error while opening file!\n");
		}

		void close()
		{
			if (filename_ == "OSTREAM")
				throw RuntimeError("close: not possible\n");
			fout_->close();
		}

		template 
		void writeline(T, PsimagLite::String, PsimagLite::OstringStream& msg, SizeType)
		{
			printline(msg);
		}

		void printline(const String& s)
		{
			if (rank_ != 0)
				return;
			(*fout_) << s << "\n";
		}

		void printline(OstringStream& s)
		{
			if (rank_ != 0)
				return;
			(*fout_) << s().str() << "\n";
			s().flush();
			s().seekp(std::ios_base::beg);
		}

		template 
		void write(const T& x, const String& label, typename EnableIf::True, int>::Type = 0)
		{
			(*fout_) << label << "=" << x << "\n";
		}

		template 
		void write(const T& something, const String& label, typename EnableIf::True, int>::Type = 0)
		{
			if (rank_ != 0)
				return;
			if (!(*fout_) || !fout_->good())
				throw RuntimeError("Out: file not open!\n");
			(*fout_) << label << "\n";
			(*fout_) << something << "\n";
		}

		int rank() { return rank_; }

		void setPrecision(SizeType x)
		{
			if (!fout_)
				return;
			fout_->precision(x);
		}

		SizeType precision(SizeType x)
		{
			if (!fout_)
				return x;
			fout_->precision(x);
			return x;
		}

		template 
		friend Out& operator<<(Out& io, const X& t)
		{
			if (io.rank_ != 0)
				return io;
			(*(io.fout_)) << t;
			return io;
		}

	private:

		int rank_;
		String filename_;
		std::ofstream* fout_;
	};

	class In
	{

	public:

		typedef int long LongIntegerType;
		static const LongIntegerType LAST_INSTANCE = -1;
		static const LongIntegerType ONLY_INSTANCE = 0;
		typedef unsigned int long LongSizeType;

		In() { }

		In(String const& fn)
		    : filename_(fn)
		    , fin_(fn.c_str())
		{
			if (!fin_ || !fin_.good() || fin_.bad()) {
				String s = "IoSimple::ctor(...): Can't open file " + filename_ + "\n";
				throw RuntimeError(s.c_str());
			}
		}

		~In() { fin_.close(); }

		bool ng() const { return false; }

		void open(String const& fn)
		{
			filename_ = fn;
			fin_.open(fn.c_str());
			if (!fin_ || !fin_.good() || fin_.bad()) {
				String s = "IoSimpleIn::open(...) failed for file " + filename_ + "\n";
				throw RuntimeError(s.c_str());
			}
		}

		void close() { fin_.close(); }

		template 
		SizeType readline(X& x, const String& s, LongIntegerType level = 0)
		{
			String temp;
			bool found = false;
			bool foundOnce = false;
			LongSizeType counter = 0;
			if (fin_.bad() || !fin_.good())
				throw RuntimeError("Readline\n");
			while (!fin_.eof()) {
				fin_ >> temp;
				if (fin_.eof())
					break;
				if (temp.substr(0, s.size()) == s) {
					foundOnce = true;
					IstringStream temp2(
					    temp.substr(s.size(), temp.size()));
					temp2 >> x;
					if (level >= 0 && counter == LongSizeType(level)) {
						found = true;
						break;
					}
					counter++;
				}
			}

			if (!foundOnce || (!found && level != LAST_INSTANCE)) {
				String emessage = "IoSimple::In::readline(): Not found " + s + " in file " + filename_;
				throw RuntimeError(emessage.c_str());
			}

			if (level == LAST_INSTANCE) {
				fin_.close();
				fin_.open(filename_.c_str());
				readline(x, s, counter - 1);
			}

			return counter;
		}

		template 
		typename EnableIf::True,
		    std::pair>::Type
		read(X& x, String const& s, LongIntegerType level = 0, bool beQuiet = false)
		{
			std::pair sc = advance(s, level, beQuiet);
			int xsize;
			fin_ >> xsize;
			if (xsize == 0)
				return sc;
			x.resize(xsize);
			for (int i = 0; i < xsize; i++) {
				typename X::value_type tmp;
				fin_ >> tmp;
				x[i] = tmp;
			}
			return sc;
		}

		template 
		void
		read(X& mat, String const& s, LongIntegerType level = 0, typename EnableIf::True, int>::Type = 0)
		{
			advance(s, level);
			fin_ >> mat;
		}

		template 
		typename EnableIf::True,
		    std::pair>::Type
		read(X& x, String const& s, LongIntegerType level = 0, bool beQuiet = false)
		{
			std::pair sc = advance(s, level, beQuiet);
			fin_ >> x;
			return sc;
		}

		std::pair advance(String const& s,
		    LongIntegerType level = 0,
		    bool beQuiet = false)
		{

			String temp = "NOTFOUND";
			String tempSaved = "NOTFOUND";
			LongSizeType counter = 0;
			bool found = false;

			while (!fin_.eof()) {
				fin_ >> temp;
				if (fin_.eof() || !fin_.good() || fin_.bad())
					break;

				if (temp.substr(0, s.size()) == s) {
					tempSaved = temp;
					if (level >= 0 && counter == LongSizeType(level)) {
						found = true;
						break;
					}
					counter++;
				}
			}

			if (level == LAST_INSTANCE && tempSaved != "NOTFOUND") {
				fin_.close();
				fin_.open(filename_.c_str());
				if (counter > 1)
					advance(s, counter - 2);
				return std::pair(tempSaved,
				    counter);
			}

			if (!found && tempSaved == "NOTFOUND") {
				if (!beQuiet) {
					std::cerr << "Not found " << s
						  << " in file " << filename_;
					std::cerr << " level=" << level
						  << " counter=" << counter
						  << "\n";
				}
				throw RuntimeError("IoSimple::In::read()\n");
			}

			return std::pair(tempSaved, counter);
		}

		SizeType count(const String& s)
		{
			SizeType i = 0;
			while (i < 1000) {
				try {
					advance(s, 0, true);
					i++;
				} catch (std::exception& e) {
					rewind();
					return i;
				}
			}

			String ss = "IoSimple::count(...): too many " + s + " in file " + filename_ + "\n";
			throw RuntimeError(s.c_str());
		}

		void rewind()
		{
			fin_.clear(); // forget we hit the end of file
			fin_.seekg(
			    0, std::ios::beg); // move to the start of the file
		}

		bool eof() const { return fin_.eof(); }

		template 
		friend void operator>>(In& io, X& t)
		{
			(io.fin_) >> t;
		}

	private:

		String filename_;
		std::ifstream fin_;
	};
}; // class IoSimple

template <>
struct IsInputLike {
	enum { True = true };
};

template <>
struct IsOutputLike {
	enum { True = true };
};

} // namespace PsimagLite

namespace Spf
{

class IoSimpleIn : public PsimagLite::IoSimple::In
{

public:

	IoSimpleIn(const char* fn)
	    : PsimagLite::IoSimple::In(PsimagLite::String(fn))
	{
	}
};
} // namespace Spf
/*@}*/
#endif
PsimagLite-3.06/src/Io/TypeToH5.cpp000066400000000000000000000020301446452427400167720ustar00rootroot00000000000000#ifndef USE_IO_SIMPLE

#include "TypeToH5.h"

namespace PsimagLite
{

template <>
H5::PredType typeToH5() { return H5::PredType::NATIVE_CHAR; }

template <>
H5::PredType typeToH5()
{
	return H5::PredType::NATIVE_UCHAR;
}

template <>
H5::PredType typeToH5() { return H5::PredType::NATIVE_HBOOL; }

template <>
H5::PredType typeToH5() { return H5::PredType::NATIVE_INT; }

template <>
H5::PredType typeToH5()
{
	return H5::PredType::NATIVE_SHORT;
}

template <>
H5::PredType typeToH5() { return H5::PredType::NATIVE_LONG; }

template <>
H5::PredType typeToH5()
{
	return H5::PredType::NATIVE_UINT;
}

template <>
H5::PredType typeToH5()
{
	return H5::PredType::NATIVE_USHORT;
}

template <>
H5::PredType typeToH5()
{
	return H5::PredType::NATIVE_ULONG;
}

template <>
H5::PredType typeToH5()
{
	return H5::PredType::NATIVE_FLOAT;
}

template <>
H5::PredType typeToH5()
{
	return H5::PredType::NATIVE_DOUBLE;
}

} // namespace PsimagLite
#endif
PsimagLite-3.06/src/Io/TypeToH5.h000066400000000000000000000006231446452427400164450ustar00rootroot00000000000000#ifndef PSI_TYPETOH5_H
#define PSI_TYPETOH5_H
#include "../AllocatorCpu.h"
#include 

namespace PsimagLite
{

template 
typename EnableIf::value, H5::PredType>::Type typeToH5();

template 
typename EnableIf::value, H5::PredType>::Type typeToH5()
{
	return H5::PredType::NATIVE_UINT8;
}
} // namespace PsimagLite
#endif // PSI_TYPETOH5_H
PsimagLite-3.06/src/IsClass.h000066400000000000000000000006311446452427400160150ustar00rootroot00000000000000#ifndef PSI_IS_CLASS_H
#define PSI_IS_CLASS_H
#include 

namespace PsimagLite
{

template 
class IsClass
{

	typedef char One;
	typedef struct {
		char a[2];
	} Two;

	template 
	static One test(int C::*);

	template 
	static Two test(...);

public:

	enum { value = sizeof(IsClass::template test(0)) == sizeof(One) };
};

} // namespace PsimagLite

#endif
PsimagLite-3.06/src/LAPACK.h000066400000000000000000000363471446452427400154240ustar00rootroot00000000000000//-*-C++-*-
// ****************************************************************************
// * C++ wrapper for BLAS                                                     *
// *                                                                          *
// * Thomas Schulthess, ORNL, October 1999                                    *
// ****************************************************************************

#ifndef PSIMAG_LAPACK
#define PSIMAG_LAPACK

#include 

/** \file LAPACK
 *  \author Thomas C. Schulthess,
 MSS
 */

namespace psimag
{

/** \brief Namespace encapsulating psimag wrappers of LAPACK functions.
 */
namespace LAPACK
{

#ifndef PSI_LAPACK_64
	typedef int IntegerForLapackType;
#else
	typedef long int IntegerForLapackType;
#endif
	// ============================================================================
	extern "C" void sgesv_(IntegerForLapackType*, IntegerForLapackType*, float*, IntegerForLapackType*, IntegerForLapackType*, float*, IntegerForLapackType*, IntegerForLapackType*);

	extern "C" void dgesv_(IntegerForLapackType*, IntegerForLapackType*, double*, IntegerForLapackType*, IntegerForLapackType*, double*, IntegerForLapackType*, IntegerForLapackType*);

	extern "C" void cgesv_(IntegerForLapackType*, IntegerForLapackType*, std::complex*, IntegerForLapackType*, IntegerForLapackType*, std::complex*, IntegerForLapackType*, IntegerForLapackType*);

	extern "C" void zgesv_(IntegerForLapackType*, IntegerForLapackType*, std::complex*, IntegerForLapackType*, IntegerForLapackType*, std::complex*, IntegerForLapackType*, IntegerForLapackType*);

	// MSS
	extern "C" IntegerForLapackType
	dgetrf_(IntegerForLapackType*, IntegerForLapackType*, double*, IntegerForLapackType*, IntegerForLapackType*, IntegerForLapackType*);

	extern "C" IntegerForLapackType
	sgetrf_(IntegerForLapackType*, IntegerForLapackType*, float*, IntegerForLapackType*, IntegerForLapackType*, IntegerForLapackType*);

	extern "C" IntegerForLapackType
	zgetrf_(IntegerForLapackType*, IntegerForLapackType*, std::complex*, IntegerForLapackType*, IntegerForLapackType*, IntegerForLapackType*);

	extern "C" IntegerForLapackType
	cgetrf_(IntegerForLapackType*, IntegerForLapackType*, std::complex*, IntegerForLapackType*, IntegerForLapackType*, IntegerForLapackType*);

	extern "C" IntegerForLapackType
	zgetri_(IntegerForLapackType*, std::complex*, IntegerForLapackType*, IntegerForLapackType*, std::complex*, IntegerForLapackType*, IntegerForLapackType*);

	extern "C" IntegerForLapackType
	cgetri_(IntegerForLapackType*, std::complex*, IntegerForLapackType*, IntegerForLapackType*, std::complex*, IntegerForLapackType*, IntegerForLapackType*);

	extern "C" IntegerForLapackType dgetri_(IntegerForLapackType*, double*, IntegerForLapackType*, IntegerForLapackType*, double*, IntegerForLapackType*, IntegerForLapackType*);

	extern "C" IntegerForLapackType sgetri_(IntegerForLapackType*, float*, IntegerForLapackType*, IntegerForLapackType*, float*, IntegerForLapackType*, IntegerForLapackType*);

	extern "C" IntegerForLapackType
	dgesdd_(char* jobz, IntegerForLapackType* m, IntegerForLapackType* n, double* a, IntegerForLapackType* lda, double* s, double* u, IntegerForLapackType* ldu, double* vt, IntegerForLapackType* ldvt, double* work, IntegerForLapackType* lwork, IntegerForLapackType* iwork, IntegerForLapackType* info);

	extern "C" IntegerForLapackType
	sgesdd_(char* jobz, IntegerForLapackType* m, IntegerForLapackType* n, float* a, IntegerForLapackType* lda, float* s, float* u, IntegerForLapackType* ldu, float* vt, IntegerForLapackType* ldvt, float* work, IntegerForLapackType* lwork, IntegerForLapackType* iwork, IntegerForLapackType* info);

	extern "C" IntegerForLapackType
	zgesdd_(char* jobz, IntegerForLapackType* m, IntegerForLapackType* n, std::complex* a, IntegerForLapackType* lda, double* s, std::complex* u, IntegerForLapackType* ldu, std::complex* vt, IntegerForLapackType* ldvt, std::complex* work, IntegerForLapackType* lwork, double* rwork, IntegerForLapackType* iwork, IntegerForLapackType* info);

	extern "C" IntegerForLapackType
	cgesdd_(char* jobz, IntegerForLapackType* m, IntegerForLapackType* n, std::complex* a, IntegerForLapackType* lda, float* s, std::complex* u, IntegerForLapackType* ldu, std::complex* vt, IntegerForLapackType* ldvt, std::complex* work, IntegerForLapackType* lwork, float* rwork, IntegerForLapackType* iwork, IntegerForLapackType* info);

	extern "C" IntegerForLapackType
	dgesvd_(char* jobz, char*, IntegerForLapackType* m, IntegerForLapackType* n, double* a, IntegerForLapackType* lda, double* s, double* u, IntegerForLapackType* ldu, double* vt, IntegerForLapackType* ldvt, double* work, IntegerForLapackType* lwork, IntegerForLapackType* info);

	extern "C" IntegerForLapackType
	sgesvd_(char* jobz, char*, IntegerForLapackType* m, IntegerForLapackType* n, float* a, IntegerForLapackType* lda, float* s, float* u, IntegerForLapackType* ldu, float* vt, IntegerForLapackType* ldvt, float* work, IntegerForLapackType* lwork, IntegerForLapackType* info);

	extern "C" IntegerForLapackType
	zgesvd_(char* jobz, char*, IntegerForLapackType* m, IntegerForLapackType* n, std::complex* a, IntegerForLapackType* lda, double* s, std::complex* u, IntegerForLapackType* ldu, std::complex* vt, IntegerForLapackType* ldvt, std::complex* work, IntegerForLapackType* lwork, double* rwork, IntegerForLapackType* info);

	extern "C" IntegerForLapackType
	cgesvd_(char* jobz, char*, IntegerForLapackType* m, IntegerForLapackType* n, std::complex* a, IntegerForLapackType* lda, float* s, std::complex* u, IntegerForLapackType* ldu, std::complex* vt, IntegerForLapackType* ldvt, std::complex* work, IntegerForLapackType* lwork, float* rwork, IntegerForLapackType* info);

	extern "C" void ilaver_(IntegerForLapackType*, IntegerForLapackType*, IntegerForLapackType*);

	extern "C" void dstedc_(char*, IntegerForLapackType*, double*, double*, double*, IntegerForLapackType*, double*, IntegerForLapackType*, IntegerForLapackType*, IntegerForLapackType*, IntegerForLapackType*);

	extern "C" void sstedc_(char*, IntegerForLapackType*, float*, float*, float*, IntegerForLapackType*, float*, IntegerForLapackType*, IntegerForLapackType*, IntegerForLapackType*, IntegerForLapackType*);

	extern "C" void zstedc_(char*, IntegerForLapackType*, double*, double*, std::complex*, IntegerForLapackType*, std::complex*, IntegerForLapackType*, double*, IntegerForLapackType*, IntegerForLapackType*, IntegerForLapackType*, IntegerForLapackType*);

	extern "C" void cstedc_(char*, IntegerForLapackType*, float*, float*, std::complex*, IntegerForLapackType*, std::complex*, IntegerForLapackType*, float*, IntegerForLapackType*, IntegerForLapackType*, IntegerForLapackType*, IntegerForLapackType*);

	extern "C" void dsterf_(IntegerForLapackType*, double*, double*, IntegerForLapackType*);

	extern "C" void ssterf_(IntegerForLapackType*, float*, float*, IntegerForLapackType*);

	extern "C" void dsteqr_(char*, IntegerForLapackType*, double*, double*, double*, IntegerForLapackType*, double*, IntegerForLapackType*);

	extern "C" void ssteqr_(char*, IntegerForLapackType*, float*, float*, float*, IntegerForLapackType*, float*, IntegerForLapackType*);

	// ============================================================================

	inline void STERF(IntegerForLapackType* n, double* d, double* e, IntegerForLapackType* info)
	{
		dsterf_(n, d, e, info);
	}

	inline void STERF(IntegerForLapackType* n, float* d, float* e, IntegerForLapackType* info)
	{
		ssterf_(n, d, e, info);
	}

	inline void STEQR(char jobz, IntegerForLapackType n, double* d, double* e, double* z, IntegerForLapackType ldz, double* work, IntegerForLapackType* info)
	{
		dsteqr_(&jobz, &n, d, e, z, &ldz, work, info);
	}

	inline void STEQR(char jobz, IntegerForLapackType n, float* d, float* e, float* z, IntegerForLapackType ldz, float* work, IntegerForLapackType* info)
	{
		ssteqr_(&jobz, &n, d, e, z, &ldz, work, info);
	}

	inline void GESV(IntegerForLapackType ma, IntegerForLapackType mb, float* a, IntegerForLapackType lda, IntegerForLapackType* pivot, float* b, IntegerForLapackType ldb, int& info)
	{
		sgesv_(&ma, &mb, a, &lda, pivot, b, &ldb, &info);
	}

	inline void GESV(IntegerForLapackType ma, IntegerForLapackType mb, double* a, IntegerForLapackType lda, IntegerForLapackType* pivot, double* b, IntegerForLapackType ldb, int& info)
	{
		dgesv_(&ma, &mb, a, &lda, pivot, b, &ldb, &info);
	}

	inline void GESV(IntegerForLapackType ma, IntegerForLapackType mb, std::complex* a, IntegerForLapackType lda, IntegerForLapackType* pivot, std::complex* b, IntegerForLapackType ldb, int& info)
	{
		cgesv_(&ma, &mb, a, &lda, pivot, b, &ldb, &info);
	}

	inline void GESV(IntegerForLapackType ma, IntegerForLapackType mb, std::complex* a, IntegerForLapackType lda, IntegerForLapackType* pivot, std::complex* b, IntegerForLapackType ldb, int& info)
	{
		zgesv_(&ma, &mb, a, &lda, pivot, b, &ldb, &info);
	}

	inline void GETRF(IntegerForLapackType ma, IntegerForLapackType na, double* a, IntegerForLapackType lda, IntegerForLapackType* pivot, int& info)
	{
		dgetrf_(&ma, &na, a, &lda, pivot, &info);
	}

	inline void GETRF(IntegerForLapackType ma, IntegerForLapackType na, std::complex* a, IntegerForLapackType lda, IntegerForLapackType* pivot, int& info)
	{
		zgetrf_(&ma, &na, a, &lda, pivot, &info);
	}

	inline void GETRF(IntegerForLapackType ma, IntegerForLapackType na, float* a, IntegerForLapackType lda, IntegerForLapackType* pivot, int& info)
	{
		sgetrf_(&ma, &na, a, &lda, pivot, &info);
	}

	inline void GETRF(IntegerForLapackType ma, IntegerForLapackType na, std::complex* a, IntegerForLapackType lda, IntegerForLapackType* pivot, int& info)
	{
		cgetrf_(&ma, &na, a, &lda, pivot, &info);
	}

	inline void GETRI(IntegerForLapackType na, double* a, IntegerForLapackType lda, IntegerForLapackType* pivot, double* work, IntegerForLapackType lwork, int& info)
	{
		dgetri_(&na, a, &lda, pivot, work, &lwork, &info);
	}

	inline void GETRI(IntegerForLapackType na, std::complex* a, IntegerForLapackType lda, IntegerForLapackType* pivot, std::complex* work, IntegerForLapackType lwork, int& info)
	{
		zgetri_(&na, a, &lda, pivot, work, &lwork, &info);
	}

	inline void GETRI(IntegerForLapackType na, float* a, IntegerForLapackType lda, IntegerForLapackType* pivot, float* work, IntegerForLapackType lwork, int& info)
	{
		sgetri_(&na, a, &lda, pivot, work, &lwork, &info);
	}

	inline void GETRI(IntegerForLapackType na, std::complex* a, IntegerForLapackType lda, IntegerForLapackType* pivot, std::complex* work, IntegerForLapackType lwork, int& info)
	{
		cgetri_(&na, a, &lda, pivot, work, &lwork, &info);
	}

	inline void GESDD(char* jobz, IntegerForLapackType* m, IntegerForLapackType* n, double* a,
	    // T*,
	    IntegerForLapackType* lda,
	    double* s,
	    double* u,
	    // T*,
	    IntegerForLapackType* ldu,
	    double* vt,
	    // T*,
	    IntegerForLapackType* ldvt,
	    double* work,
	    // T*,
	    IntegerForLapackType* lwork,
	    double*,
	    // nothing
	    IntegerForLapackType* iwork,

	    IntegerForLapackType* info)
	{
		dgesdd_(jobz, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, iwork, info);
	}

	inline void GESDD(char* jobz, IntegerForLapackType* m, IntegerForLapackType* n, float* a,
	    // T*,
	    IntegerForLapackType* lda,
	    float* s,
	    float* u,
	    // T*,
	    IntegerForLapackType* ldu,
	    float* vt,
	    // T*,
	    IntegerForLapackType* ldvt,
	    float* work,
	    // T*,
	    IntegerForLapackType* lwork,
	    float*,
	    // nothing
	    IntegerForLapackType* iwork,

	    IntegerForLapackType* info)
	{
		sgesdd_(jobz, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, iwork, info);
	}

	inline void GESDD(char* jobz, IntegerForLapackType* m, IntegerForLapackType* n, std::complex* a,
	    // T*,
	    IntegerForLapackType* lda,
	    double* s,
	    std::complex* u,
	    // T*,
	    IntegerForLapackType* ldu,
	    std::complex* vt,
	    // T*,
	    IntegerForLapackType* ldvt,
	    std::complex* work,
	    // T*,
	    IntegerForLapackType* lwork,
	    double* rwork,
	    // nothing
	    IntegerForLapackType* iwork,
	    IntegerForLapackType* info)
	{
		zgesdd_(jobz, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, rwork, iwork, info);
	}

	inline void GESDD(char* jobz, IntegerForLapackType* m, IntegerForLapackType* n, std::complex* a,
	    // T*,
	    IntegerForLapackType* lda,

	    float* s,
	    std::complex* u,
	    // T*,
	    IntegerForLapackType* ldu,
	    std::complex* vt,
	    // T*,
	    IntegerForLapackType* ldvt,
	    std::complex* work,
	    // T*,
	    IntegerForLapackType* lwork,
	    float* rwork,
	    // nothing
	    IntegerForLapackType* iwork,
	    IntegerForLapackType* info)
	{
		cgesdd_(jobz, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, rwork, iwork, info);
	}

	inline void GESVD(char* jobz, char* jobvt, IntegerForLapackType* m, IntegerForLapackType* n, double* a,
	    // T*,
	    IntegerForLapackType* lda,
	    double* s,
	    double* u,
	    // T*,
	    IntegerForLapackType* ldu,
	    double* vt,
	    // T*,
	    IntegerForLapackType* ldvt,
	    double* work,
	    // T*,
	    IntegerForLapackType* lwork,
	    double*,
	    // nothing
	    IntegerForLapackType* info)
	{
		dgesvd_(jobz, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, info);
	}

	inline void GESVD(char* jobz, char* jobvt, IntegerForLapackType* m, IntegerForLapackType* n, float* a,
	    // T*,
	    IntegerForLapackType* lda,
	    float* s,
	    float* u,
	    // T*,
	    IntegerForLapackType* ldu,
	    float* vt,
	    // T*,
	    IntegerForLapackType* ldvt,
	    float* work,
	    // T*,
	    IntegerForLapackType* lwork,
	    float*,
	    // nothing
	    IntegerForLapackType* info)
	{
		sgesvd_(jobz, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, info);
	}

	inline void GESVD(char* jobz, char* jobvt, IntegerForLapackType* m, IntegerForLapackType* n, std::complex* a,
	    // T*,
	    IntegerForLapackType* lda,
	    double* s,
	    std::complex* u,
	    // T*,
	    IntegerForLapackType* ldu,
	    std::complex* vt,
	    // T*,
	    IntegerForLapackType* ldvt,
	    std::complex* work,
	    // T*,
	    IntegerForLapackType* lwork,
	    double* rwork,
	    // nothing
	    IntegerForLapackType* info)
	{
		zgesvd_(jobz, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, rwork, info);
	}

	inline void GESVD(char* jobz, char* jobvt, IntegerForLapackType* m, IntegerForLapackType* n, std::complex* a,
	    // T*,
	    IntegerForLapackType* lda,
	    float* s,
	    std::complex* u,
	    // T*,
	    IntegerForLapackType* ldu,
	    std::complex* vt,
	    // T*,
	    IntegerForLapackType* ldvt,
	    std::complex* work,
	    // T*,
	    IntegerForLapackType* lwork,
	    float* rwork,
	    // nothing
	    IntegerForLapackType* info)
	{
		cgesvd_(jobz, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, rwork, info);
	}

	inline bool isThreadSafe()
	{
		IntegerForLapackType major = 0;
		IntegerForLapackType minor = 0;
		IntegerForLapackType patch = 0;
		ilaver_(&major, &minor, &patch);
		if (major < 3)
			return false;
		return (minor >= 3);
	}
} /* namespace LAPACK */
} /* namespace psimag */

#endif // PSIMAG_LAPACK_H
PsimagLite-3.06/src/LabelDisabled.h000066400000000000000000000006641446452427400171310ustar00rootroot00000000000000#ifndef LABEL_DISABLED_H
#define LABEL_DISABLED_H
#include "Vector.h"

namespace PsimagLite
{

class LabelDisabled
{

	typedef Vector::Type VectorStringType;

public:

	void disable(String label) { data_.push_back(label); }

	bool operator()(String label) const
	{
		return (find(data_.begin(), data_.end(), label) != data_.end());
	}

private:

	VectorStringType data_;
};

} // namespace PsimagLite
#endif // LABEL_DISABLED_H
PsimagLite-3.06/src/LanczosCore.h000066400000000000000000000222451446452427400167030ustar00rootroot00000000000000/*
Copyright (c) 2009-2011-2017, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 2.]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file LanczosCore.h
 *
 *  A class to represent a generic Lanczos Solver
 *
 */

#ifndef PSI_LANCZOS_CORE_H
#define PSI_LANCZOS_CORE_H
#include "ContinuedFraction.h"
#include "LanczosVectors.h"
#include "Matrix.h"
#include "ProgressIndicator.h"
#include "Random48.h"
#include "TridiagonalMatrix.h"
#include "Vector.h"
#include 

namespace PsimagLite
{

//! MatrixType must have the following interface:
//! 	RealType type to indicate the matrix type
//! 	rows() member function to indicate the rank of the matrix
//! 	matrixVectorProduct(typename Vector< RealType>::Type& x,const
//!     typename Vector< RealType>::Type& const y)
//!    	   member function that implements the operation x += Hy

template 
class LanczosCore
{

	typedef LanczosVectors LanczosVectorsType;

public:

	typedef VectorType_ VectorType;
	typedef typename LanczosVectorsType::DenseMatrixType DenseMatrixType;
	typedef typename LanczosVectorsType::VectorVectorType VectorVectorType;
	typedef typename SolverParametersType::RealType RealType;
	typedef typename LanczosVectorsType::DenseMatrixRealType
	    DenseMatrixRealType;
	typedef typename PsimagLite::Vector::Type VectorRealType;
	typedef SolverParametersType ParametersSolverType;
	typedef MatrixType LanczosMatrixType;
	typedef typename LanczosVectorsType::TridiagonalMatrixType
	    TridiagonalMatrixType;
	typedef typename VectorType::value_type VectorElementType;
	typedef ContinuedFraction PostProcType;

	LanczosCore(const MatrixType& mat, const SolverParametersType& params, bool isReorthoEnabled)
	    : progress_("LanczosCore")
	    , mat_(mat)
	    , params_(params)
	    , steps_(params.steps)
	    , lanczosVectors_(mat_, params.lotaMemory, params.steps, isReorthoEnabled)
	{
		OstringStream msg(std::cout.precision());
		msg() << "Constructing... mat.rank=" << mat_.rows();
		msg() << " maximum steps=" << steps_
		      << " maximum eps=" << params_.tolerance << " requested";
		progress_.printline(msg, std::cout);
	}

	/**
	 *     In each step of the Lanczos algorithm the values of a[]
	 *     and b[] are computed.
	 *     then a tridiagonal matrix T[j] is formed from the matrix
	 *     T[j-1] as
	 *
	 *            | a[0]  b[0]                            |
	 *            | b[0]  a[1]  b[1]                      |
	 *     T(j) = |       b[1]    .     .                 |
	 *            |               .     .  a[j-2]  b[j-2] |
	 *            |               .     .  b[j-2]  a[j-1] |
	 */
	void decomposition(const VectorType& initVector,
	    TridiagonalMatrixType& ab,
	    SizeType excitedForStop)
	{
		SizeType& max_nstep = steps_;
		SizeType matsize = mat_.rows();

		if (initVector.size() != matsize) {
			String msg("decomposition: vector size ");
			msg += ttos(initVector.size()) + " but matrix size ";
			msg += ttos(matsize) + "\n";
			throw RuntimeError(msg);
		}

		VectorType V2(matsize, 0); // v2
		VectorType V1(matsize, 0); // v1
		VectorType V0 = initVector; // v0

		RealType atmp = 0;
		for (SizeType i = 0; i < matsize; ++i)
			atmp += PsimagLite::real(V0[i] * PsimagLite::conj(V0[i]));

		atmp = 1.0 / sqrt(atmp);
		for (SizeType i = 0; i < matsize; ++i)
			V0[i] *= atmp;

		if (max_nstep > matsize)
			max_nstep = matsize;
		ab.resize(max_nstep, 0);

		bool exitFlag = false;
		SizeType j = 0;
		lanczosVectors_.saveInitialVector(V0);
		lanczosVectors_.prepareMemory(matsize, max_nstep);

		// -- 1st step --
		ab.b(0) = 0.0; // beta_0 = 0 always
		if (lanczosVectors_.lotaMemory())
			lanczosVectors_.saveVector(V0, 0);
		for (SizeType i = 0; i < matsize; ++i)
			V1[i] = 0.0;
		mat_.matrixVectorProduct(V1, V0); // V1 = H|V0>
		atmp = 0.0;
		for (SizeType i = 0; i < matsize; ++i)
			atmp += PsimagLite::real(
			    V1[i] * PsimagLite::conj(V0[i])); // alpha = 
		ab.a(0) = atmp;

		RealType btmp = 0.0;
		for (SizeType i = 0; i < matsize; ++i) {
			V1[i] -= atmp * V0[i]; // V1 = V1 - alpha*V0
			btmp += PsimagLite::real(V1[i] * PsimagLite::conj(V1[i]));
		}

		btmp = sqrt(btmp);
		ab.b(1) = btmp; // beta = sqrt(V1*V1)

		if (btmp > 0) {
			btmp = 1.0 / btmp;
			for (SizeType i = 0; i < matsize; ++i)
				V1[i] *= btmp; // normalize V1
		}

		if (lanczosVectors_.lotaMemory() && 1 < max_nstep)
			lanczosVectors_.saveVector(V1, 1);

		VectorRealType tmpEigs(ab.size(), 0);
		VectorRealType eold(ab.size(), 0);
		RealType deltaMax = 0;

		// ---- Starting the loop -------
		for (j = 1; j < max_nstep; ++j) {

			lanczosVectors_.oneStepDecomposition(V0, V1, V2, ab, j);
			ab.diag(tmpEigs, j + 1);
			const SizeType eigsForError = std::min(excitedForStop,
			    static_cast(tmpEigs.size()));

			deltaMax = 0;
			for (SizeType ii = 0; ii < eigsForError; ++ii) {
				const RealType delta = fabs(tmpEigs[ii] - eold[ii]);
				eold[ii] = tmpEigs[ii];
				if (delta > deltaMax)
					deltaMax = delta;
			}

			if (deltaMax < params_.tolerance)
				exitFlag = true;
			if (j == max_nstep - 1)
				exitFlag = true;
			if (exitFlag && mat_.rows() <= 4)
				break;
			if (exitFlag && j >= params_.minSteps)
				break;

			if (lanczosVectors_.lotaMemory())
				lanczosVectors_.saveVector(V2, j + 1);

			for (SizeType i = 0; i < matsize; ++i) {
				V0[i] = V1[i];
				V1[i] = V2[i];
			}
		}

		if (j < max_nstep) {
			max_nstep = j + 1;
			ab.resize(max_nstep);
		}

		lanczosVectors_.resize(max_nstep);

		OstringStream msg(std::cout.precision());
		msg() << "Decomposition done for mat.rank=" << mat_.rows();
		msg() << " after " << j << " steps";
		if (params_.tolerance > 0)
			msg() << ", actual eps=" << deltaMax;

		progress_.printline(msg, std::cout);

		if (j == max_nstep && j != mat_.rows()) {
			OstringStream msg2(std::cout.precision());
			msg2() << "WARNING: Maximum number of steps used. ";
			msg2() << "Increasing this maximum is recommended.";
			progress_.printline(msg2, std::cout);
		}
	}

	void excitedVector(VectorType& z, const DenseMatrixType& ritz, SizeType excited) const
	{
		lanczosVectors_.excitedVector(z, ritz, excited);
	}

	SizeType steps() const { return steps_; }

	void lanczosVectorsSwap(DenseMatrixType& V)
	{
		DenseMatrixType* ptr = lanczosVectors_.data();
		if (!ptr)
			throw RuntimeError("LanczosCore::lanczosVectors() "
					   "called but no data stored\n");

		ptr->swap(V);
	}

	const MatrixType& matrix() const { return mat_; }

	const SolverParametersType& params() const { return params_; }

private:

	ProgressIndicator progress_;
	const MatrixType& mat_;
	const SolverParametersType& params_;
	SizeType steps_;
	LanczosVectorsType lanczosVectors_;
}; // class LanczosCore

} // namespace PsimagLite

/*@}*/
#endif
PsimagLite-3.06/src/LanczosOrDavidsonBase.h000066400000000000000000000077251446452427400206640ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file LanczosOrDavidsonBase.h
 *
 *  Virtual class to select lanczos or davidson
 *
 */

#ifndef LANCZOS_OR_DAVIDSON_BASE_H
#define LANCZOS_OR_DAVIDSON_BASE_H
#include 

namespace PsimagLite
{

template 
class LanczosOrDavidsonBase
{

public:

	typedef typename SolverParametersType::RealType RealType;
	typedef typename Vector::Type VectorRealType;
	typedef typename Vector::Type VectorVectorType;
	typedef MatrixType_ MatrixType;

	// To avoid compiler warnings
	virtual ~LanczosOrDavidsonBase() { }

	virtual void computeOneState(RealType&, VectorType&, const VectorType&, SizeType) = 0;

	virtual void computeAllStatesBelow(VectorRealType&, VectorVectorType&, const VectorType&, SizeType) = 0;

	static bool isReorthoEnabled(const SolverParametersType& params)
	{
		if (params.options.find("reortho") == PsimagLite::String::npos)
			return false;

		bool canReortho = (params.lotaMemory);

		if (!canReortho) {
			PsimagLite::String str("LanczosOrDavidsonBase: Reortho "
					       "requested but cannot");
			str += "Suggestion: Delete reortho from input or set "
			       "lotaMemory=true\n";
			throw PsimagLite::RuntimeError(str);
		}

		return true;
	}

}; // class LanczosOrDavidsonBase

} // namespace PsimagLite

/*@}*/
#endif // LANCZOS_OR_DAVIDSON_BASE_H
PsimagLite-3.06/src/LanczosSolver.h000066400000000000000000000061651446452427400172700ustar00rootroot00000000000000#ifndef PSI_LANCZOS_SOLVER_H
#define PSI_LANCZOS_SOLVER_H
#include "LanczosCore.h"
#include "LanczosOrDavidsonBase.h"
#include "Profiling.h"
#include "Vector.h"

namespace PsimagLite
{

template 
class LanczosSolver : public LanczosOrDavidsonBase
{

public:

	typedef LanczosOrDavidsonBase
	    BaseType;
	typedef LanczosCore
	    LanczosCoreType;
	typedef typename LanczosCoreType::TridiagonalMatrixType
	    TridiagonalMatrixType;
	typedef typename LanczosCoreType::RealType RealType;
	typedef typename LanczosCoreType::VectorType VectorType;
	typedef typename Vector::Type VectorVectorType;
	typedef typename LanczosCoreType::VectorRealType VectorRealType;
	typedef MatrixType_ MatrixType;
	typedef ContinuedFraction PostProcType;
	typedef SolverParametersType ParametersSolverType;

	LanczosSolver(const MatrixType& mat, const SolverParametersType& params)
	    : ls_(mat, params, BaseType::isReorthoEnabled(params))
	{
	}

	void computeOneState(RealType& energy, VectorType& z, const VectorType& initialVector, SizeType excited)
	{
		Profiling profiling("LanczosSolver", std::cout);

		TridiagonalMatrixType ab;
		ls_.decomposition(initialVector, ab, excited);

		VectorRealType eigs(ab.size());
		typename LanczosCoreType::DenseMatrixType ritz;
		ab.buildDenseMatrix(ritz);
		diag(ritz, eigs, 'V');

		energy = eigs[excited];
		ls_.excitedVector(z, ritz, excited);

		String str = "LanczosSolver: computeOneState: ";
		if (norm(z) < 1e-6)
			throw RuntimeError(str + " norm is zero\n");

		const RealType norma = norm(initialVector);
		const SizeType iter = ls_.steps();

		if (norma < 1e-5 || norma > 100)
			std::cerr << "norma=" << norma << "\n";

		OstringStream msg(std::cout.precision());
		String what = "lowest";
		if (excited > 0)
			what = ttos(excited) + " excited";
		msg() << "Found " << what << " eigenvalue= " << energy
		      << " after " << iter;
		msg() << " iterations, "
		      << " orig. norm=" << norma << " excited=" << excited;
		profiling.end(msg().str());
	}

	void computeAllStatesBelow(VectorRealType& eigs, VectorVectorType& z, const VectorType& initialVector, SizeType excited)
	{
		TridiagonalMatrixType ab;
		ls_.decomposition(initialVector, ab, excited);

		if (excited > ab.size())
			throw RuntimeError("Excited too big\n");

		typename LanczosCoreType::DenseMatrixType ritz;
		ab.buildDenseMatrix(ritz);
		diag(ritz, eigs, 'V');

		SizeType n = z.size();
		if (n > excited + 1)
			n = excited + 1;
		for (SizeType i = 0; i < n; ++i)
			ls_.excitedVector(z[i], ritz, i);
	}

	void decomposition(const VectorType& initVector,
	    TridiagonalMatrixType& ab)
	{
		return ls_.decomposition(initVector, ab, ls_.params().eigsForStop);
	}

	void lanczosVectorsSwap(typename LanczosCoreType::DenseMatrixType& V)
	{
		ls_.lanczosVectorsSwap(V);
	}

	SizeType steps() const { return ls_.steps(); }

private:

	LanczosCoreType ls_;
};
} // namespace PsimagLite
#endif // PSI_LANCZOS_SOLVER_H
PsimagLite-3.06/src/LanczosVectors.h000066400000000000000000000206161446452427400174400ustar00rootroot00000000000000/*
Copyright (c) 2009-2013-2018, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 5.]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/

/** \ingroup PsimagLite */
/*@{*/

/*! \file LanczosVectors.h
 *
 *  to store or not to store lanczos vectors
 *
 */

#ifndef LANCZOS_VECTORS_HEADER_H
#define LANCZOS_VECTORS_HEADER_H
#include "ContinuedFraction.h"
#include "Matrix.h"
#include "ProgressIndicator.h"
#include "Random48.h"
#include "Vector.h"
#include 

namespace PsimagLite
{

template 
class LanczosVectors
{

	typedef typename VectorType_::value_type ComplexOrRealType;
	typedef typename Real::Type RealType;
	typedef LanczosVectors ThisType;

public:

	typedef MatrixType_ MatrixType;
	typedef VectorType_ VectorType;
	typedef TridiagonalMatrix TridiagonalMatrixType;
	typedef typename VectorType::value_type VectorElementType;
	typedef Matrix DenseMatrixType;
	typedef Matrix DenseMatrixRealType;
	typedef ContinuedFraction PostProcType;
	typedef typename PsimagLite::Vector::Type VectorVectorType;

	enum { WITH_INFO = 1,
		DEBUG = 2,
		ALLOWS_ZERO = 4 };

	LanczosVectors(const MatrixType& mat, bool lotaMemory, SizeType steps, bool isReorthoEnabled)
	    : progress_("LanczosVectors")
	    , mat_(mat)
	    , lotaMemory_(lotaMemory)
	    , isReorthoEnabled_(isReorthoEnabled)
	    , dummy_(0)
	    , needsDelete_(false)
	    , ysaved_(0)
	    , data_(0)
	    , overlap_(0)
	{
		if (!lotaMemory)
			throw RuntimeError(
			    "LanczosVectors: support for lotaMemory=false has "
			    "been removed\n");

		dealWithOverlapStorage(steps);
	}

	~LanczosVectors()
	{
		delete overlap_;
		overlap_ = 0;

		if (!needsDelete_)
			return;

		delete data_;
		data_ = 0;
	}

	void saveVector(const VectorType& y, SizeType j)
	{
		if (!lotaMemory_)
			return;

		SizeType rows = data_->rows();
		for (SizeType i = 0; i < rows; ++i)
			data_->operator()(i, j) = y[i];
	}

	void prepareMemory(SizeType rows, SizeType steps)
	{
		if (!lotaMemory_)
			return;

		dealWithStorageOfV(rows, steps);

		if (overlap_)
			overlap_->resize(steps, 0);
		else
			overlap_ = new VectorType(steps, 0);
	}

	void resize(SizeType x)
	{
		SizeType rows = data_->rows();
		data_->resize(rows, x);
	}

	const DenseMatrixType* data() const { return data_; }

	DenseMatrixType* data() { return data_; }

	VectorElementType data(SizeType i, SizeType j)
	{
		return data_->operator()(i, j);
	}

	SizeType cols() const { return data_->cols(); }

	SizeType rows() const { return data_->rows(); }

	bool lotaMemory() const { return lotaMemory_; }

	void saveInitialVector(const VectorType& y) { ysaved_ = y; }

	void excitedVector(VectorType& z, const DenseMatrixType& ritz, SizeType excited) const
	{
		SizeType small = data_->cols();
		SizeType big = data_->rows();
		for (SizeType j = 0; j < small; j++) {
			ComplexOrRealType ctmp = ritz(j, excited);
			for (SizeType i = 0; i < big; i++)
				z[i] += ctmp * data_->operator()(i, j);
		}
	}

	void oneStepDecomposition(VectorType& V0, VectorType& V1, VectorType& V2, TridiagonalMatrixType& ab, SizeType iter) const
	{
		SizeType nn = V1.size();
		for (SizeType h = 0; h < nn; h++)
			V2[h] = 0.0;
		mat_.matrixVectorProduct(V2, V1); // V2 = H|V1>

		RealType atmp = 0.0;
		for (SizeType h = 0; h < nn; h++)
			atmp += PsimagLite::real(
			    V2[h] * PsimagLite::conj(V1[h])); // 
		ab.a(iter) = atmp;

		RealType btmp = 0.0;
		for (SizeType h = 0; h < nn; h++) {
			V2[h] = V2[h] - ab.a(iter) * V1[h] - ab.b(iter) * V0[h]; // V2 = V2 - alpha*V1 - beta*V0;
			btmp += PsimagLite::real(V2[h] * PsimagLite::conj(V2[h]));
		}

		btmp = sqrt(btmp);
		if (iter + 1 < ab.size())
			ab.b(iter + 1) = btmp; // beta = sqrt(V2*V2)

		if (btmp > 0) {
			btmp = 1.0 / btmp;
			for (SizeType i = 0; i < nn; i++)
				V2[i] *= btmp; // normalize V2
		}

		reorthoIfNecessary(V2, iter);
	}

	void needsDelete(bool b) { needsDelete_ = b; }

private:

	void reorthoIfNecessary(VectorType& V2, SizeType iter) const
	{
		if (!isReorthoEnabled_)
			return;

		if (!overlap_ || overlap_->size() <= iter)
			throw RuntimeError("reorthoIfNecessary failed\n");

		SizeType nn = V2.size();
		// cout << "  Re-orthogonalization " << endl;
		for (SizeType i = 0; i < iter + 1; i++) {

			VectorElementType rij = 0.0;
			for (SizeType h = 0; h < nn; h++)
				rij += PsimagLite::conj(data_->operator()(h, i)) * V2[h];

			// V2 = V2 -  Vi -- gram-schmid
			for (SizeType h = 0; h < nn; h++)
				V2[h] = V2[h] - data_->operator()(h, i) * rij;
		}

		RealType ntmp = 0.0;
		for (SizeType h = 0; h < nn; h++)
			ntmp += PsimagLite::real(V2[h] * PsimagLite::conj(V2[h]));

		ntmp = 1.0 / sqrt(ntmp);
		for (SizeType h = 0; h < nn; h++)
			V2[h] = V2[h] * ntmp;
	}

	void dealWithStorageOfV(SizeType rows, SizeType cols)
	{
		if (!lotaMemory_)
			return;

		if (data_) {
			if (rows != data_->rows() || cols != data_->cols())
				throw RuntimeError("LanczosVectors: data has "
						   "already been set!\n");
			return;
		}

		data_ = new DenseMatrixType(rows, cols);
		needsDelete_ = true;
		OstringStream msg(std::cout.precision());
		msg() << "lotaMemory_=true";
		progress_.printline(msg, std::cout);
	}

	void dealWithOverlapStorage(SizeType steps)
	{
		if (!isReorthoEnabled_)
			return;

		OstringStream msg(std::cout.precision());
		msg() << "Reortho enabled";
		progress_.printline(msg, std::cout);
		return;

		SizeType maxNstep = std::min(steps, mat_.rows());
		overlap_ = new VectorType(maxNstep, 0);
	}

	//! copy ctor and assigment operator are invalid
	//! because this class contains a pointer:
	ThisType& operator=(const ThisType& other);

	LanczosVectors(const ThisType& copy);

	ProgressIndicator progress_;
	const MatrixType& mat_;
	bool lotaMemory_;
	bool isReorthoEnabled_;
	VectorElementType dummy_;
	bool needsDelete_;
	VectorType ysaved_;
	DenseMatrixType* data_;
	VectorType* overlap_;
}; // class LanczosVectors

} // namespace PsimagLite

/*@}*/
#endif // LANCZOS_VECTORS_HEADER_H
PsimagLite-3.06/src/LapackExtra.h000066400000000000000000000032771446452427400166640ustar00rootroot00000000000000// BEGIN LICENSE BLOCK
/*
Copyright (c) 2009 , UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************

*/
// END LICENSE BLOCK

#ifndef LAPACK_H_
#define LAPACK_H_
#include 

#ifndef PSI_LAPACK_64
typedef int IntegerForLapackType;
#else
typedef long int IntegerForLapackType;
#endif

extern "C" void zheev_(char*, char*, IntegerForLapackType*, std::complex*, IntegerForLapackType*, double*, std::complex*, IntegerForLapackType*, double*, IntegerForLapackType*);
extern "C" void cheev_(char*, char*, IntegerForLapackType*, std::complex*, IntegerForLapackType*, float*, std::complex*, IntegerForLapackType*, float*, IntegerForLapackType*);
extern "C" void dsyev_(char*, char*, IntegerForLapackType*, double*, IntegerForLapackType*, double*, double*, IntegerForLapackType*, IntegerForLapackType*);
extern "C" void ssyev_(char*, char*, IntegerForLapackType*, float*, IntegerForLapackType*, float*, float*, IntegerForLapackType*, IntegerForLapackType*);

extern "C" void zgeev_(char*, char*, IntegerForLapackType*, std::complex*, IntegerForLapackType*, std::complex*, std::complex*, IntegerForLapackType*, std::complex*, IntegerForLapackType*, std::complex*, IntegerForLapackType*, double*, IntegerForLapackType*);
#endif
PsimagLite-3.06/src/Limit.h000066400000000000000000000017451446452427400155410ustar00rootroot00000000000000#ifndef PSIMAGLITE_LIMIT_H
#define PSIMAGLITE_LIMIT_H
#include "Vector.h"
#include 
#include 
#include 
#include 
#include 

namespace PsimagLite
{

class Limit
{

public:

	typedef std::pair PairRlimType;

	Limit()
	    : rlimit_(new struct rlimit)
	{
	}

	~Limit()
	{
		delete rlimit_;
		rlimit_ = 0;
	}

	void memory(int s, int h = 0)
	{
		rlimit_->rlim_cur = s;
		rlimit_->rlim_max = (h > s) ? h : s;
		int ret = setrlimit(RLIMIT_AS, rlimit_);
		checkRet(ret, "setrlimit");
	}

	PairRlimType memory()
	{
		int ret = getrlimit(RLIMIT_AS, rlimit_);
		checkRet(ret, "getrlimit");
		return PairRlimType(rlimit_->rlim_cur, rlimit_->rlim_max);
	}

private:

	void checkRet(int x, PsimagLite::String msg) const
	{
		if (x == 0)
			return;
		std::cerr << "Call to " << msg << " failed\n";
		std::cerr << strerror(errno) << "\n";
		// FIXME: should we throw here?
	}

	struct rlimit* rlimit_;
};
}; // namespace PsimagLite
#endif
PsimagLite-3.06/src/LineMarker.h000066400000000000000000000023371446452427400165120ustar00rootroot00000000000000
/*
// BEGIN LICENSE BLOCK
Copyright (c) 2009 , UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************

*/
/** \ingroup DMRG */
/*@{*/

/*! \file LineMarker.h
 *
 * Writes a line to disk, intended as a mark
 */

#ifndef LINE_MARKER_H
#define LINE_MARKER_H
#include "AllocatorCpu.h"
#include 

namespace PsimagLite
{

class LineMarker
{
public:

	LineMarker(const String& name)
	    : name_(name + "=0")
	{
	}

	template 
	LineMarker(IoInputType& io, const String& name, SizeType level = 0)
	{
		name_ = name + "=0";
		SizeType x = 0; // bogus
		io.readline(x, name_, level);
	}

	template 
	void save(IoOutputType& io) const
	{
		io.printline(name_);
	}

private:

	String name_;

}; // class LineMarker
} // namespace PsimagLite
/*@}*/
#endif // LINE_MARKER_H
PsimagLite-3.06/src/LinearPrediction.h000066400000000000000000000161371446452427400177170ustar00rootroot00000000000000// BEGIN LICENSE BLOCK
/*
Copyright (c) 2009 , UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************


*/
// END LICENSE BLOCK
/** \ingroup PsimagLite */
/*@{*/

/*! \file LinearPrediction.h
 *
 *  Extrapolating a "time" series
 *  see extrapolation.tex for more details
 */

#ifndef LINEAR_PREDICTION_H
#define LINEAR_PREDICTION_H
#include "BLAS.h"
#include "LAPACK.h"
#include "Matrix.h"
#include 

#ifdef USE_GSL
extern "C" {
#include 
}
#endif

namespace PsimagLite
{

template 
class LinearPrediction
{
	typedef Matrix MatrixType;

public:

	LinearPrediction(const typename Vector::Type& y, SizeType p)
	    : y_(y)
	    , p_(p)
	{
		SizeType ysize = y.size();
		if (ysize & 1)
			throw RuntimeError(
			    "LinearPrediction::ctor(...): data set must "
			    "contain an even number of points\n");
		SizeType n = ysize / 2;
		MatrixType A(p, p);
		typename Vector::Type B(p);
		computeA(A, n);
		computeB(B, n);
		computeD(A, B);
	}

	const FieldType& operator()(SizeType i) const { return y_[i]; }

	void linearPredictionfunction(const typename Vector::Type& y,
	    SizeType p)
	{
		SizeType ysize = y.size();
		if (ysize & 1)
			throw RuntimeError(
			    "LinearPrediction::ctor(...): data set must "
			    "contain an even number of points\n");
		SizeType n = ysize / 2;
		MatrixType A(p, p);
		typename Vector::Type B(p);
		computeA(A, n);
		computeB(B, n);
		computeD(A, B);
	}

	void predict(SizeType p)
	{
		SizeType n = y_.size();
		for (SizeType i = n; i < n + p; i++) {
			FieldType sum = 0;
			for (SizeType j = 0; j < d_.size(); j++) {
				sum += d_[j] * y_[i - j - 1];
			}
			y_.push_back(sum);
		}
	}

	void predict2(SizeType p)
	{
		// Fix roots
		typedef std::complex Complex;
		SizeType twicep = 2 * p;
		SizeType pp1 = p + 1;
		typename Vector::Type nd(p), aa(pp1), zz(twicep);
		std::vector roots(p);
		std::vector ab(pp1);

		aa[p] = 1;
		for (SizeType j = 0; j < p; j++) {
			aa[j] = -d_[p - 1 - j];
		}

#ifdef USE_GSL
		gsl_poly_complex_workspace* w = gsl_poly_complex_workspace_alloc(pp1);
		gsl_poly_complex_solve(&aa[0], pp1, w, &zz[0]);
		gsl_poly_complex_workspace_free(w);
#else
		throw RuntimeError("Please compile with USE_GSL defined\n");
#endif

		for (SizeType j = 0; j < p; j++) {
			roots[j] = Complex(zz[2 * j], zz[2 * j + 1]);
		}

		for (SizeType j = 0; j < p; j++) {
			// Look for a root outside the unit circle, and put it
			// to 0
			if (abs(roots[j]) > 1.0) {
				roots[j] = 0.0; // roots[j]/abs(roots[j]);
			}
		}
		// Now reconstruct the polynomial coefficients
		ab[0] = -roots[0];
		ab[1] = 1.0;
		for (SizeType j = 1; j < p; j++) {
			ab[j + 1] = 1.0;
			for (SizeType i = j; i >= 1; i--) {
				ab[i] = ab[i - 1] - roots[j] * ab[i];
			}
			ab[0] = -roots[j] * ab[0];
		}
		for (SizeType j = 0; j < p; j++) {
			nd[p - 1 - j] = -PsimagLite::real(ab[j]);
		}

		SizeType n = y_.size();
		y_.resize(n + p);
		for (SizeType i = n; i < n + p; i++) {
			FieldType sum = 0;
			for (SizeType j = 0; j < d_.size(); j++) {
				sum += nd[j] * y_[i - j - 1];
			}
			y_[i] = sum;
		}
	}

private:

	//! Note: A and B cannot be const. here due to the ultimate
	//! call to BLAS::GEMV
	void computeD(MatrixType& A, typename Vector::Type& B)
	{
		SizeType p = B.size();
		typename Vector::Type ipiv(
		    p); // use signed integers here!!
		int info = 0;
		psimag::LAPACK::GETRF(p, p, &(A(0, 0)), p, &(ipiv[0]), info);

		typename Vector::Type work(2);
		int lwork = -1; // query mode
		psimag::LAPACK::GETRI(p, &(A(0, 0)), p, &(ipiv[0]), &(work[0]), lwork, info);
		lwork = static_cast(work[0]);
		if (lwork <= 0)
			throw RuntimeError(
			    "LinearPrediction:: internal error\n");
		work.resize(lwork);
		// actual work:
		psimag::LAPACK::GETRI(p, &(A(0, 0)), p, &(ipiv[0]), &(work[0]), lwork, info);

		d_.resize(p);
		psimag::BLAS::GEMV('N', p, p, 1.0, &(A(0, 0)), p, &(B[0]), 1, 0.0, &(d_[0]), 1);
	}

	void computeA(MatrixType& A, SizeType n) const
	{
		SizeType p = A.rows();
		for (SizeType l = 0; l < p; l++) {
			for (SizeType j = 0; j < p; j++) {
				A(l, j) = 0;
				for (SizeType i = n; i < 2 * n; i++)
					A(l, j) += y_[i - l - 1] * y_[i - j - 1];
			}
		}
	}

	void computeB(typename Vector::Type& B, SizeType n) const
	{
		SizeType p = B.size();
		for (SizeType l = 0; l < p; l++) {
			B[l] = 0;
			for (SizeType i = n; i < 2 * n; i++)
				B[l] += y_[i - l - 1] * y_[i];
		}
	}

	typename Vector::Type y_;
	SizeType p_;
	typename Vector::Type d_;
}; // class LinearPrediction
} // namespace PsimagLite

/*@}*/
#endif // LINEAR_PREDICTION_H
PsimagLite-3.06/src/LoadBalancerDefault.h000066400000000000000000000014001446452427400202630ustar00rootroot00000000000000#ifndef LOADBALANCERDEFAULT_H
#define LOADBALANCERDEFAULT_H
#include "Sort.h"
#include "Vector.h"

namespace PsimagLite
{

class LoadBalancerDefault
{

public:

	typedef PsimagLite::Vector::Type VectorSizeType;

	LoadBalancerDefault(SizeType ntasks, SizeType nthreads)
	    : blockSize_(ntasks / nthreads)
	{
		if (ntasks < nthreads && ntasks > 0) {
			nthreads = ntasks;
			blockSize_ = 1;
		}

		assert(nthreads > 0);
		if ((ntasks % nthreads) != 0)
			++blockSize_;
	}

	SizeType blockSize(SizeType) const { return blockSize_; }

	SizeType taskNumber(SizeType threadNum, SizeType p) const
	{
		return p + threadNum * blockSize_;
	}

private:

	SizeType blockSize_;
}; // class LoadBalancerDefault
} // namespace PsimagLite
#endif // LOADBALANCERDEFAULT_H
PsimagLite-3.06/src/LoadBalancerMpi.h000066400000000000000000000013531446452427400174330ustar00rootroot00000000000000#ifndef LOADBALANCER_MPI_H
#define LOADBALANCER_MPI_H
#include "Sort.h"
#include "Vector.h"

namespace PsimagLite
{

class LoadBalancerMpi
{

public:

	typedef PsimagLite::Vector::Type VectorSizeType;

	LoadBalancerMpi(SizeType ntasks, SizeType nthreads)
	    : blockSize_(ntasks / nthreads)
	{
		if (ntasks < nthreads && ntasks > 0) {
			nthreads = ntasks;
			blockSize_ = 1;
		}

		assert(nthreads > 0);
		if ((ntasks % nthreads) != 0)
			++blockSize_;
	}

	SizeType blockSize(SizeType) const { return blockSize_; }

	SizeType taskNumber(SizeType threadNum, SizeType p) const
	{
		return p + threadNum * blockSize_;
	}

private:

	SizeType blockSize_;
}; // class LoadBalancerMpi
} // namespace PsimagLite
#endif // LOADBALANCER_MPI_H
PsimagLite-3.06/src/LoadBalancerWeights.h000066400000000000000000000040261446452427400203200ustar00rootroot00000000000000#ifndef LOADBALANCERWEIGHTS_H
#define LOADBALANCERWEIGHTS_H
#include "Sort.h"
#include "Vector.h"

namespace PsimagLite
{

class LoadBalancerWeights
{

public:

	typedef PsimagLite::Vector::Type VectorSizeType;

	LoadBalancerWeights(SizeType ntasks, SizeType nthreads)
	    : LoadBalancerWeights(VectorSizeType(ntasks, 1),
		nthreads) // ctor delegation
	{
	}

	LoadBalancerWeights(const VectorSizeType& weights, SizeType nthreads)
	    : taskNumber_(nthreads)
	{
		SizeType ntasks = weights.size();
		if (ntasks < nthreads && ntasks > 0)
			nthreads = ntasks;
		VectorSizeType workLoad(nthreads, 0);
		VectorSizeType weights2 = weights;
		VectorSizeType iperm(ntasks, 0);
		Sort sort;
		sort.sort(weights2, iperm);

		for (SizeType iii = 0; iii < ntasks; ++iii) {
			SizeType ii = ntasks - 1 - iii; // because sort is ascending
			SizeType thread = findThreadWithLightestWork(workLoad);
			// assign work to thread
			assert(thread < taskNumber_.size());
			taskNumber_[thread].push_back(iperm[ii]);
			// update work loads
			assert(thread < workLoad.size());
			workLoad[thread] += weights[iperm[ii]];
		}

#ifdef DEBUG_PTHREADS_NG
		for (SizeType i = 0; i < nthreads; ++i) {
			SizeType n = taskNumber_[i].size();
			std::cout << n << " Indices allocated to thread " << i
				  << ": ";
			for (SizeType j = 0; j < n; ++j)
				std::cout << taskNumber_[i][j] << " ";
			std::cout << "\n";
		}
#endif
	}

	SizeType blockSize(SizeType threadNum) const
	{
		assert(threadNum < taskNumber_.size());
		return taskNumber_[threadNum].size();
	}

	int taskNumber(SizeType threadNum, SizeType p) const
	{
		assert(threadNum < taskNumber_.size());
		assert(p < taskNumber_[threadNum].size());
		return taskNumber_[threadNum][p];
	}

private:

	SizeType
	findThreadWithLightestWork(const VectorSizeType& workLoad) const
	{
		return std::min_element(workLoad.begin(), workLoad.end()) - workLoad.begin();
	}

	PsimagLite::Vector::Type taskNumber_;
}; // class LoadBalancerWeights
} // namespace PsimagLite
#endif // LOADBALANCERWEIGHTS_H
PsimagLite-3.06/src/Map.h000066400000000000000000000030101446452427400151630ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*!
 *
 *
 */
#ifndef MAP_HEADER_H
#define MAP_HEADER_H
#include "AllocatorCpu.h"
#include 

namespace PsimagLite
{

template >
class Map
{
public:

	typedef std::map>::Type>
	    Type;
}; // class Map

template 
class IsMapLike
{
public:

	enum { True = false };
};

template 
class IsMapLike>::Type>>
{
public:

	enum { True = true };
};

template 
typename EnableIf::True, void>::Type
printMap(std::ostream& os, const MapType& x, const String& label)
{
	typedef typename MapType::const_iterator MapIteratorType;
	for (MapIteratorType it = x.begin(); it != x.end(); ++it) {
		os << label << "[" << it->first << "]=" << it->second << "\n";
	}
}

} // namespace PsimagLite

/*@}*/
#endif // MAP_HEADER_H
PsimagLite-3.06/src/Matrix.cpp000066400000000000000000000114311446452427400162530ustar00rootroot00000000000000#include "Matrix.h"

namespace PsimagLite
{

void checkBlasStatus(int info, PsimagLite::String msg)
{
	if (info == 0)
		return;

	PsimagLite::String str = msg;
	str += " failed with info = " + ttos(info) + "\n";
	throw RuntimeError(str);
}

void diag(Matrix& m, Vector::Type& eigs, char option)
{
#ifdef NO_LAPACK
	throw RuntimeError("diag: dsyev_: NO LAPACK!\n");
#else
	char jobz = option;
	char uplo = 'U';
	int n = m.rows();
	int lda = m.cols();
	Vector::Type work(3);
	int info;
	int lwork = -1;

	if (lda <= 0)
		throw RuntimeError("lda<=0\n");

	eigs.resize(n);

	// query:
	dsyev_(&jobz, &uplo, &n, &(m(0, 0)), &lda, &(eigs[0]), &(work[0]), &lwork, &info);
	if (info != 0) {
		std::cerr << "info=" << info << "\n";
		throw RuntimeError("diag: dsyev_: failed with info!=0.\n");
	}

	const int NB = 256;
	lwork = std::max(1 + static_cast(work[0]), (NB + 2) * n);
	work.resize(lwork);
	// real work:
	dsyev_(&jobz, &uplo, &n, &(m(0, 0)), &lda, &(eigs[0]), &(work[0]), &lwork, &info);
	if (info != 0) {
		std::cerr << "info=" << info << "\n";
		throw RuntimeError("diag: dsyev_: failed with info!=0.\n");
	}
#endif
}

void diag(Matrix>& m, Vector::Type& eigs, char option)
{
#ifdef NO_LAPACK
	throw RuntimeError("diag: zheev: NO LAPACK!\n");
#else
	char jobz = option;
	char uplo = 'U';
	int n = m.rows();
	int lda = m.cols();
	Vector>::Type work(3);
	Vector::Type rwork(3 * n);
	int info;
	int lwork = -1;

	eigs.resize(n);

	// query:
	zheev_(&jobz, &uplo, &n, &(m(0, 0)), &lda, &(eigs[0]), &(work[0]), &lwork, &(rwork[0]), &info);
	if (info != 0) {
		std::cerr << "info=" << info << "\n";
		throw RuntimeError("diag: zheev_: failed with info!=0.\n");
	}

	const int NB = 256;
	lwork = std::max(1 + static_cast(std::real(work[0])), (NB + 2) * n);
	work.resize(lwork);
	// real work:
	zheev_(&jobz, &uplo, &n, &(m(0, 0)), &lda, &(eigs[0]), &(work[0]), &lwork, &(rwork[0]), &info);
	if (info != 0) {
		std::cerr << "info=" << info << "\n";
		throw RuntimeError("diag: zheev: failed with info!=0.\n");
	}
#endif
}

void diag(Matrix& m, Vector::Type& eigs, char option)
{
#ifdef NO_LAPACK
	throw RuntimeError("diag: dsyev_: NO LAPACK!\n");
#else
	char jobz = option;
	char uplo = 'U';
	int n = m.rows();
	int lda = m.cols();
	Vector::Type work(3);
	int info;
	int lwork = -1;

	if (lda <= 0)
		throw RuntimeError("lda<=0\n");

	eigs.resize(n);

	// query:
	ssyev_(&jobz, &uplo, &n, &(m(0, 0)), &lda, &(eigs[0]), &(work[0]), &lwork, &info);
	if (info != 0) {
		std::cerr << "info=" << info << "\n";
		throw RuntimeError("diag: dsyev_: failed with info!=0.\n");
	}

	const int NB = 256;
	lwork = std::max(1 + static_cast(work[0]), (NB + 2) * n);
	work.resize(lwork);

	// real work:
	ssyev_(&jobz, &uplo, &n, &(m(0, 0)), &lda, &(eigs[0]), &(work[0]), &lwork, &info);
	if (info != 0) {
		std::cerr << "info=" << info << "\n";
		throw RuntimeError("diag: dsyev_: failed with info!=0.\n");
	}
#endif
}

void diag(Matrix>& m, Vector::Type& eigs, char option)
{
#ifdef NO_LAPACK
	throw RuntimeError("diag: cheev: NO LAPACK!\n");
#else
	char jobz = option;
	char uplo = 'U';
	int n = m.rows();
	int lda = m.cols();
	Vector>::Type work(3);
	Vector::Type rwork(3 * n);
	int info, lwork = -1;

	eigs.resize(n);

	// query:
	cheev_(&jobz, &uplo, &n, &(m(0, 0)), &lda, &(eigs[0]), &(work[0]), &lwork, &(rwork[0]), &info);
	if (info != 0) {
		std::cerr << "info=" << info << "\n";
		throw RuntimeError("diag: cheev_: failed with info!=0.\n");
	}

	const int NB = 256;
	lwork = std::max(1 + static_cast(std::real(work[0])), (NB + 2) * n);
	work.resize(lwork);

	// real work:
	cheev_(&jobz, &uplo, &n, &(m(0, 0)), &lda, &(eigs[0]), &(work[0]), &lwork, &(rwork[0]), &info);
	if (info != 0) {
		std::cerr << "info=" << info << "\n";
		throw RuntimeError("diag: cheev: failed with info!=0.\n");
	}
#endif
}

void geev(char jobvl, char jobvr, Matrix>& a, Vector>::Type& w, Matrix>& vl, Matrix>& vr)
{
#ifdef NO_LAPACK
	throw RuntimeError("diag: geev: NO LAPACK!\n");
#else
	int n = a.rows();
	int lda = a.cols();
	int ldvl = vl.rows();
	int ldvr = vr.rows();
	int info = 0;
	Vector>::Type work(10, 0);
	Vector::Type rwork(2 * n + 1, 0);
	int lwork = -1;
	zgeev_(&jobvl, &jobvr, &n, &(a(0, 0)), &lda, &(w[0]), &(vl(0, 0)), &ldvl, &(vr(0, 0)), &ldvr, &(work[0]), &lwork, &(rwork[0]), &info);

	const int NB = 256;
	lwork = std::max(1 + static_cast(std::real(work[0])), (NB + 2) * n);
	work.resize(lwork);

	zgeev_(&jobvl, &jobvr, &n, &(a(0, 0)), &lda, &(w[0]), &(vl(0, 0)), &ldvl, &(vr(0, 0)), &ldvr, &(work[0]), &lwork, &(rwork[0]), &info);

	checkBlasStatus(info, "zgeev_");
#endif
}

} // namespace PsimagLite
PsimagLite-3.06/src/Matrix.h000066400000000000000000000654641446452427400157370ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************

*/
#ifndef MATRIX_H_
#define MATRIX_H_

#include "BLAS.h"
#include "Complex.h"
#include "Io/IoSerializerStub.h"
#include "LAPACK.h"
#include "LapackExtra.h"
#include "Mpi.h"
#include "TypeToString.h"
#include "Vector.h"
#include 
#include 
#include 
#include 
#include 

namespace PsimagLite
{

template 
void expComplexOrReal(RealType& x, const RealType& y)
{
	x = exp(y);
}

template 
void expComplexOrReal(std::complex& x, const RealType& y)
{
	x = std::complex(cos(y), sin(y));
}

template 
class MatrixNonOwned;

template 
class Matrix
{
public:

	typedef T value_type; // legacy name

	Matrix()
	    : nrow_(0)
	    , ncol_(0)
	{
	}

	Matrix(SizeType nrow, SizeType ncol)
	    : nrow_(nrow)
	    , ncol_(ncol)
	    , data_(nrow * ncol)
	{
	}

	Matrix(SizeType nrow, SizeType ncol, const T& value)
	    : nrow_(nrow)
	    , ncol_(ncol)
	    , data_(nrow * ncol, value)
	{
	}

	Matrix(const typename Vector::Type& data, SizeType nrow, SizeType ncol)
	    : nrow_(nrow)
	    , ncol_(ncol)
	    , data_(data)
	{
		if (data.size() < nrow * ncol)
			throw RuntimeError("Matrix::ctor failed\n");

		data_.resize(nrow * ncol);
	}

	template 
	Matrix(
	    const Matrix& m,
	    typename EnableIf::True, int>::Type = 0)
	{
		nrow_ = m.rows();
		ncol_ = m.cols();
		data_.resize(nrow_ * ncol_);
		for (SizeType i = 0; i < nrow_; i++)
			for (SizeType j = 0; j < ncol_; j++)
				data_[i + j * nrow_] = m(i, j);
	}

	Matrix(std::ifstream& io)
	{
		io >> nrow_;
		io >> ncol_;
		if (nrow_ <= 0 || ncol_ <= 0)
			throw RuntimeError("Matrix::nrows or ncols negative: "
					   "cannot construct\n");

		data_.resize(nrow_ * ncol_);
		for (SizeType i = 0; i < nrow_; ++i)
			for (SizeType j = 0; j < ncol_; ++j)
				io >> data_[i + j * nrow_];
	}

	// ctor closures
	Matrix(const std::ClosureOperator& c)
	{
		const T f1 = 1.0;
		matrixMatrix(c.r1, c.r2, f1);
	}

	template 
	Matrix(const std::ClosureOperator<
		   std::ClosureOperator,
		   Matrix,
		   std::ClosureOperations::OP_MULT>& c,
	    typename EnableIf::isArith, int>::Type = 0)
	{
		*this = c.r1.r1 * c.r1.r2 * c.r2;
	}

	template 
	Matrix(const std::ClosureOperator<
		   T1,
		   std::ClosureOperator,
		   std::ClosureOperations::OP_MULT>& c,
	    typename EnableIf::isArith, int>::Type = 0)
	{
		*this = c.r1 * (c.r2.r1 + c.r2.r2);
	}
	// end all ctors

	void read(int fd)
	{
		::read(fd, &ncol_, sizeof(ncol_));
		::read(fd, &nrow_, sizeof(nrow_));
		data_.resize(nrow_ * ncol_);
		::read(fd, &(data_[0]), sizeof(T) * nrow_ * ncol_);
	}

	void read(String label, IoSerializer& ioSerializer)
	{
		ioSerializer.read(nrow_, label + "/nrow_");
		ioSerializer.read(ncol_, label + "/ncol_");
		if (nrow_ == 0 || ncol_ == 0)
			return;
		ioSerializer.read(data_, label + "/data_");
	}

	void
	write(String label, IoSerializer& ioSerializer, IoSerializer::WriteMode wM = IoSerializer::NO_OVERWRITE) const
	{
		bool flag = false;
		if (wM == IoSerializer::ALLOW_OVERWRITE)
			flag = overwrite(label, ioSerializer);

		if (flag)
			return;

		ioSerializer.createGroup(label);
		ioSerializer.write(label + "/nrow_", nrow_);
		ioSerializer.write(label + "/ncol_", ncol_);
		if (nrow_ == 0 || ncol_ == 0)
			return;
		ioSerializer.write(label + "/data_", data_);
	}

	bool overwrite(String label, IoSerializer& ioSerializer) const
	{
		bool b = ioSerializer.write(label + "/nrow_", nrow_, IoSerializer::ALLOW_OVERWRITE);
		if (!b)
			return b;

		b = ioSerializer.write(label + "/ncol_", ncol_, IoSerializer::ALLOW_OVERWRITE);
		if (!b)
			return b;

		if (nrow_ == 0 || ncol_ == 0)
			return b;
		ioSerializer.write(label + "/data_", data_, IoSerializer::ALLOW_OVERWRITE);
		return true;
	}

	void print(int fd) const
	{
		::write(fd, (const void*)&ncol_, sizeof(ncol_));
		::write(fd, (const void*)&nrow_, sizeof(nrow_));
		::write(fd, (const void*)&(data_[0]), sizeof(T) * nrow_ * ncol_);
	}

	template 
	SizeType memResolv(SomeMemResolvType& mres, SizeType, String msg) const
	{
		String str = msg;
		str += "Matrix";
		const char* start = (const char*)&nrow_;
		const char* end = (const char*)&ncol_;
		SizeType total = mres.memResolv(&nrow_, end - start, str + " nrow_");

		start = end;
		end = (const char*)&data_;
		total += mres.memResolv(&ncol_, end - start, str + " ncol_");

		total += mres.memResolv(&data_, sizeof(*this) - total, str + " data_");

		return total;
	}

	void clear()
	{
		nrow_ = ncol_ = 0;
		data_.clear();
	}

	// default assigment operator is fine

	void conjugate()
	{
		SizeType n = data_.size();
		for (SizeType i = 0; i < n; ++i)
			data_[i] = PsimagLite::conj(data_[i]);
	}

	SizeType nonZeros() const
	{
		const T zval = 0.0;
		SizeType n = nrow_ * ncol_;
		assert(data_.size() >= n);
		SizeType count = 0;
		for (SizeType i = 0; i < n; ++i)
			if (data_[i] != zval)
				++count;

		return count;
	}

#ifndef NO_DEPRECATED_ALLOWED
	SizeType n_row() const
	{
		return nrow_;
	} // legacy name

	SizeType n_col() const { return ncol_; } // legacy name
#endif

	SizeType rows() const
	{
		return nrow_;
	}

	SizeType cols() const { return ncol_; }

	const typename Vector::Type data() const { return data_; }

	const T& operator()(SizeType i, SizeType j) const
	{
		assert(i < nrow_ && j < ncol_);
		assert(i + j * nrow_ < data_.size());
		return data_[i + j * nrow_];
	}

	T& operator()(SizeType i, SizeType j)
	{
		assert(i < nrow_ && j < ncol_);
		assert(i + j * nrow_ < data_.size());
		return data_[i + j * nrow_];
	}

	bool operator==(const Matrix& other) const
	{
		return (nrow_ == other.nrow_ && ncol_ == other.ncol_ && data_ == other.data_);
	}

	void resize(SizeType nrow, SizeType ncol, const T& val)
	{
		nrow_ = nrow;
		ncol_ = ncol;
		data_.resize(nrow * ncol, val);
	}

	void resize(SizeType nrow, SizeType ncol)
	{
		if (nrow_ > 0 && nrow_ != nrow)
			throw RuntimeError("Matrix::resize: not allowed to "
					   "change rows from non-zero\n");

		nrow_ = nrow;
		ncol_ = ncol;
		data_.resize(nrow * ncol);
	}

	Matrix& operator+=(const Matrix& other)
	{
		assert(data_.size() == ncol_ * nrow_);
		SizeType total = std::min(data_.size(), other.data_.size());
		for (SizeType i = 0; i < total; ++i)
			data_[i] += other.data_[i];
		return *this;
	}

	Matrix& operator-=(const Matrix& other)
	{
		// domain checking ???
		for (SizeType i = 0; i < ncol_ * nrow_; i++)
			data_[i] -= other.data_[i];
		return *this;
	}

	Matrix& operator*=(const T& value)
	{
		for (SizeType i = 0; i < ncol_ * nrow_; i++)
			data_[i] *= value;
		return *this;
	}

	void print(std::ostream& os, const double& eps) const
	{
		os << nrow_ << " " << ncol_ << "\n";
		for (SizeType i = 0; i < nrow_; i++) {
			for (SizeType j = 0; j < ncol_; j++) {
				T val = data_[i + j * nrow_];
				if (PsimagLite::norm(val) < eps)
					val = 0.0;
				os << val << " ";
			}
			os << "\n";
		}
	}

	void swap(Matrix& m)
	{
		m.data_.swap(data_);
		SizeType row = m.nrow_;
		SizeType col = m.ncol_;
		m.nrow_ = nrow_;
		m.ncol_ = ncol_;
		nrow_ = row;
		ncol_ = col;
	}

	void setTo(const T& val)
	{
		for (SizeType i = 0; i < data_.size(); i++)
			data_[i] = val;
	}

	void setToIdentity()
	{
		if (nrow_ != ncol_) {
			throw RuntimeError(
			    "setToIdentity called on a non-square matrix\n");
		}

		this->setTo(0);
		for (SizeType i = 0; i < nrow_; ++i) {
			this->operator()(i, i) = 1;
		}
	}

	void send(int root, int tag, MPI::CommType mpiComm)
	{
		MPI::send(nrow_, root, tag, mpiComm);
		MPI::send(ncol_, root, tag + 1, mpiComm);
		MPI::send(data_, root, tag + 2, mpiComm);
	}

	void recv(int root, int tag, MPI::CommType mpiComm)
	{
		MPI::recv(nrow_, root, tag, mpiComm);
		MPI::recv(ncol_, root, tag + 1, mpiComm);
		MPI::recv(data_, root, tag + 2, mpiComm);
	}

	void bcast(int root, MPI::CommType mpiComm)
	{
		MPI::bcast(nrow_, root, mpiComm);
		MPI::bcast(ncol_, root, mpiComm);
		MPI::bcast(data_, root, mpiComm);
	}

	// start closure members

	template 
	Matrix& operator+=(const std::ClosureOperator<
	    T1,
	    Matrix,
	    std::ClosureOperations::OP_MULT>& c)
	{
		nrow_ = c.r2.nrow_;
		ncol_ = c.r2.ncol_;

		const SizeType cSize = c.r2.data_.size();
		resizeIfNeeded(cSize);

		this->data_ += c.r1 * c.r2.data_;
		return *this;
	}

	template 
	Matrix& operator+=(const std::ClosureOperator<
	    Matrix,
	    T1,
	    std::ClosureOperations::OP_MULT>& c)
	{
		nrow_ = c.r1.nrow_;
		ncol_ = c.r1.ncol_;

		const SizeType cSize = c.r1.data_.size();
		resizeIfNeeded(cSize);

		this->data_ += c.r2 * c.r1.data_;
		return *this;
	}

	template 
	Matrix& operator=(const std::ClosureOperator<
	    T1,
	    Matrix,
	    std::ClosureOperations::OP_MULT>& c)
	{
		nrow_ = c.r2.nrow_;
		ncol_ = c.r2.ncol_;
		this->data_ <= c.r1* c.r2.data_;
		return *this;
	}

	template 
	Matrix& operator=(const std::ClosureOperator<
	    Matrix,
	    T1,
	    std::ClosureOperations::OP_MULT>& c)
	{
		nrow_ = c.r1.nrow_;
		ncol_ = c.r1.ncol_;
		this->data_ <= c.r2* c.r1.data_;
		return *this;
	}

	template 
	Matrix& operator=(const std::ClosureOperator<
	    std::ClosureOperator,
	    Matrix,
	    std::ClosureOperations::OP_MULT>& c)
	{
		matrixMatrix(c.r1.r2, c.r2, c.r1.r1);
		return *this;
	}

	template 
	Matrix& operator=(const std::ClosureOperator<
	    T1,
	    std::ClosureOperator,
	    std::ClosureOperations::OP_MULT>& c)
	{
		this->nrow_ = c.r2.r1.nrow_;
		this->ncol_ = c.r2.r1.ncol_;
		this->data_ <= c.r1*(c.r2.r1.data_ + c.r2.r2.data_);
		return *this;
	}

	template 
	Matrix&
	operator=(const std::ClosureOperator<
	    T1,
	    std::ClosureOperator,
	    std::ClosureOperations::OP_MULT>& c)
	{
		this->nrow_ = c.r2.r1.nrow_;
		this->ncol_ = c.r2.r1.ncol_;
		this->data_ <= c.r1*(c.r2.r1.data_ - c.r2.r2.data_);
		return *this;
	}

	Matrix& operator=(const std::ClosureOperator<
	    Matrix,
	    Matrix,
	    std::ClosureOperations::OP_PLUS>& c)
	{
		nrow_ = c.r1.nrow_;
		ncol_ = c.r1.ncol_;
		assert(nrow_ == c.r2.nrow_);
		assert(ncol_ == c.r2.ncol_);
		this->data_ <= c.r1.data_ + c.r2.data_;
		return *this;
	}

	Matrix& operator=(const std::ClosureOperator<
	    Matrix,
	    Matrix,
	    std::ClosureOperations::OP_MINUS>& c)
	{
		nrow_ = c.r1.nrow_;
		ncol_ = c.r1.ncol_;
		assert(nrow_ == c.r2.nrow_);
		assert(ncol_ == c.r2.ncol_);
		this->data_ <= c.r1.data_ - c.r2.data_;
		return *this;
	}

	template 
	Matrix& operator=(const std::ClosureOperator<
	    Matrix,
	    std::ClosureOperator,
	    std::ClosureOperations::OP_PLUS>& c)
	{
		nrow_ = c.r1.nrow_;
		ncol_ = c.r1.ncol_;
		assert(nrow_ == c.r2.r2.nrow_);
		assert(ncol_ == c.r2.r2.ncol_);
		this->data_ <= c.r1.data_ + c.r2.r1* c.r2.r2.data_;
		return *this;
	}

	template 
	Matrix& operator=(const std::ClosureOperator<
	    std::ClosureOperator,
	    Matrix,
	    std::ClosureOperations::OP_PLUS>& c)
	{
		nrow_ = c.r2.nrow_;
		ncol_ = c.r2.ncol_;
		assert(nrow_ == c.r1.r2.nrow_);
		assert(ncol_ == c.r1.r2.ncol_);
		this->data_ <= c.r2.data_ + c.r1.r1* c.r1.r2.data_;
		return *this;
	}

	Matrix& operator=(
	    const std::ClosureOperator, Matrix, std::ClosureOperations::OP_MULT>& c)
	{
		const Matrix& a = c.r1;
		const Matrix& b = c.r2;
		const T f1 = 1.0;
		matrixMatrix(a, b, f1);

		return *this;
	}

	// end closure members

	template 
	friend class MatrixNonOwned;

private:

	void resizeIfNeeded(const SizeType cSize)
	{
		if (this->data_.size() > 0 && cSize != this->data_.size())
			throw RuntimeError(
			    "operator+= matrices of different sizes\n");
		if (this->data_.size() == 0)
			this->data_.resize(cSize);
	}

	template 
	void matrixMatrix(const Matrix& a, const Matrix& b, const T1& t1)
	{
		Matrix m(a.rows(), b.cols());
		assert(a.cols() == b.rows());
		for (SizeType i = 0; i < a.rows(); i++) {
			for (SizeType j = 0; j < b.cols(); j++) {
				T sum = 0.0;
				for (SizeType k = 0; k < a.cols(); k++) {
					sum += a(i, k) * b(k, j);
				}

				m(i, j) = sum * t1;
			}
		}

		*this = m; // copy is needed in case a or b are *this matrix
	}

	SizeType nrow_;
	SizeType ncol_;
	typename Vector::Type data_;
}; // class Matrix

// start in Matrix.cpp
void geev(char jobvl, char jobvr, Matrix>& a, Vector>::Type& w, Matrix>& vl, Matrix>& vr);

void diag(Matrix& m, Vector::Type& eigs, char option);

void diag(Matrix>& m, Vector::Type& eigs, char option);

void diag(Matrix& m, Vector::Type& eigs, char option);

void diag(Matrix>& m, Vector::Type& eigs, char option);

template 
typename std::enable_if::True, void>::type
inverse(Matrix& m)
{
#ifdef NO_LAPACK
	throw RuntimeError("inverse: NO LAPACK!\n");
#else
	int n = m.rows();
	int info = 0;
	Vector::Type ipiv(n, 0);
	psimag::LAPACK::GETRF(n, n, &(m(0, 0)), n, &(ipiv[0]), info);
	int lwork = -1;
	typename Vector::Type work(2);
	psimag::LAPACK::GETRI(n, &(m(0, 0)), n, &(ipiv[0]), &(work[0]), lwork, info);
	lwork = static_cast(PsimagLite::real(work[0]));
	work.resize(lwork + 2);
	psimag::LAPACK::GETRI(n, &(m(0, 0)), n, &(ipiv[0]), &(work[0]), lwork, info);
	String s = "[cz]getri_ failed\n";
	if (info != 0)
		throw RuntimeError(s.c_str());
#endif
}

template 
typename std::enable_if::isArith, void>::type
inverse(Matrix& m)
{
#ifdef NO_LAPACK
	throw RuntimeError("inverse: NO LAPACK!\n");
#else
	int n = m.rows();
	int info = 0;
	Vector::Type ipiv(n, 0);
	psimag::LAPACK::GETRF(n, n, &(m(0, 0)), n, &(ipiv[0]), info);
	int lwork = -1;
	typename Vector::Type work(2);
	psimag::LAPACK::GETRI(n, &(m(0, 0)), n, &(ipiv[0]), &(work[0]), lwork, info);
	lwork = static_cast(work[0]);
	work.resize(lwork + 2);
	psimag::LAPACK::GETRI(n, &(m(0, 0)), n, &(ipiv[0]), &(work[0]), lwork, info);
	String s = "[sd]getri_ failed\n";
	if (info != 0)
		throw RuntimeError(s.c_str());
#endif
}

// end in Matrix.cpp

template 
class IsMatrixLike
{
public:

	enum { True = false };
};

template 
class IsMatrixLike>
{
public:

	enum { True = true };
};

template 
std::ostream& operator<<(std::ostream& os, Matrix const& A)
{
	SizeType i, j;
	os << A.rows() << " " << A.cols() << "\n";
	for (i = 0; i < A.rows(); i++) {
		for (j = 0; j < A.cols(); j++)
			os << A(i, j) << " ";
		os << "\n";
	}
	return os;
}

template 
void mathematicaPrint(std::ostream& os, const Matrix& A)
{
	os << "m:={";
	for (SizeType i = 0; i < A.rows(); i++) {
		os << "{";
		for (SizeType j = 0; j < A.cols(); j++) {
			os << A(i, j);
			if (j + 1 < A.cols())
				os << ",";
		}
		os << "}";
		if (i + 1 < A.rows())
			os << ",\n";
	}
	os << "}\n";
}

template 
void symbolicPrint(std::ostream& os, const Matrix& A)
{
	SizeType i, j;
	os << A.rows() << " " << A.cols() << "\n";
	typename Vector::Type values;
	String s = "symbolicPrint: Not enough characters\n";
	SizeType maxCharacters = 25;
	for (i = 0; i < A.rows(); i++) {
		for (j = 0; j < A.cols(); j++) {

			const T& val = A(i, j);
			if (PsimagLite::norm(val) < 1e-6) {
				os << " 0 ";
				continue;
			}

			SizeType k = 0;
			for (; k < values.size(); k++)
				if (PsimagLite::norm(values[k] - val) < 1e-6)
					break;
			bool b1 = (k == values.size());

			SizeType k2 = 0;
			for (; k2 < values.size(); k2++)
				if (PsimagLite::norm(values[k2] + val) < 1e-6)
					break;

			bool b2 = (k2 == values.size());

			if (b1) {
				if (b2) {
					values.push_back(val);
					if (values.size() > maxCharacters)
						throw RuntimeError(s.c_str());
					char chark = k + 65;
					os << " " << chark << " ";
				} else {
					char chark = k2 + 65;
					os << "-" << chark << " ";
				}
			} else {
				char chark = k + 65;
				os << " " << chark << " ";
			}
		}
		os << "\n";
	}
	os << "---------------------------\n";
	for (SizeType i = 0; i < values.size(); i++) {
		char chari = i + 65;
		os << chari << "=" << values[i] << " ";
	}
	os << "\n";
}

template 
void printNonZero(const Matrix& m, std::ostream& os)
{
	os << "#size=" << m.rows() << "x" << m.cols() << "\n";
	for (SizeType i = 0; i < m.rows(); i++) {
		SizeType nonzero = 0;
		for (SizeType j = 0; j < m.cols(); j++) {
			const T& val = m(i, j);
			if (val != static_cast(0)) {
				os << val << " ";
				nonzero++;
			}
		}
		if (nonzero > 0)
			os << "\n";
	}
	os << "#diagonal non-zero\n";
	for (SizeType i = 0; i < m.rows(); i++) {
		const T& val = m(i, i);
		if (val != static_cast(0)) {
			os << val << " ";
		}
	}
	os << "\n";
}

template 
std::istream& operator>>(std::istream& is, Matrix& A)
{
	SizeType nrow = 0, ncol = 0;
	is >> nrow;
	is >> ncol;

	if (is) {
		A.resize(nrow, ncol);
		for (SizeType j = 0; j < A.rows(); j++)
			for (SizeType i = 0; i < A.cols(); i++)
				is >> A(j, i);
	} else {
		String str("ERROR istream& operator >> ");
		str += "(std::istream&, Matrix&): read past end stream";
		throw RangeError(str);
	}

	return is;
}

template 
bool isHermitian(Matrix const& A, bool verbose = false)
{
	SizeType n = A.rows();
	double eps = 1e-6;
	if (n != A.cols())
		throw RuntimeError(
		    "isHermitian called on a non-square matrix.\n");
	for (SizeType i = 0; i < n; i++)
		for (SizeType j = 0; j < n; j++) {
			if (PsimagLite::norm(A(i, j) - PsimagLite::conj(A(j, i))) > eps) {
				if (verbose) {
					std::cerr << "A(" << i << "," << j
						  << ")=" << A(i, j);
					std::cerr << " A(" << j << "," << i
						  << ")=" << A(j, i) << "\n";
				}
				return false;
			}
		}
	return true;
}

template 
bool isAntiHermitian(const Matrix& A, bool verbose = false)
{
	SizeType n = A.rows();
	double eps = 1e-6;
	if (n != A.cols())
		throw RuntimeError(
		    "isHermitian called on a non-square matrix.\n");
	for (SizeType i = 0; i < n; ++i) {
		for (SizeType j = 0; j < n; ++j) {
			if (PsimagLite::norm(A(i, j) + PsimagLite::conj(A(j, i))) > eps) {
				if (verbose) {
					std::cerr << "A(" << i << "," << j
						  << ")=" << A(i, j);
					std::cerr << " A(" << j << "," << i
						  << ")=" << A(j, i) << "\n";
				}

				return false;
			}
		}
	}

	return true;
}

template 
bool isTheIdentity(Matrix const& a)
{

	for (SizeType i = 0; i < a.rows(); i++) {
		for (SizeType j = 0; j < a.cols(); j++) {
			if (i != j && PsimagLite::norm(a(i, j)) > 1e-6) {
				std::cerr << "a(" << i << "," << j
					  << ")=" << a(i, j) << "\n";
				return false;
			}
		}
	}

	for (SizeType i = 0; i < a.rows(); i++)
		if (PsimagLite::norm(a(i, i) - static_cast(1.0)) > 1e-6)
			return false;

	return true;
}

template 
bool isZero(Matrix> const& a)
{

	for (SizeType i = 0; i < a.rows(); i++)
		for (SizeType j = 0; j < a.cols(); j++)
			if (PsimagLite::norm(a(i, j)) > 0)
				return false;
	return true;
}

template 
bool isZero(const Matrix& m)
{
	for (SizeType i = 0; i < m.rows(); i++)
		for (SizeType j = 0; j < m.cols(); j++)
			if (fabs(m(i, j)) > 0)
				return false;
	return true;
}

template 
void rotate(Matrix& m, const Matrix& transform)
{
	Matrix C(transform.cols(), m.cols());

	// C = transform^\dagger * m
	psimag::BLAS::GEMM('C', 'N', transform.cols(), m.cols(), m.rows(), 1.0, &(transform(0, 0)), transform.rows(), &(m(0, 0)), m.rows(), 0.0, &(C(0, 0)), C.rows());

	// m = C * transform
	m.clear();
	m.resize(C.rows(), transform.cols());
	psimag::BLAS::GEMM('N', 'N', C.rows(), transform.cols(), transform.rows(), 1.0, &(C(0, 0)), C.rows(), &(transform(0, 0)), transform.rows(), 0.0, &(m(0, 0)), m.rows());
}

// closures start

template 
typename EnableIf<
    (IsMatrixLike::True || IsMatrixLike::True) && !std::IsClosureLike::True && !std::IsClosureLike::True,
    std::ClosureOperator>::Type
operator*(const T1& a, const T2& b)
{
	return std::ClosureOperator(a,
	    b);
}

template 
std::ClosureOperator, Matrix, std::ClosureOperations::OP_PLUS>
operator+(const Matrix& a, const Matrix& b)
{
	return std::ClosureOperator, Matrix, std::ClosureOperations::OP_PLUS>(a, b);
}

template 
std::ClosureOperator, Matrix, std::ClosureOperations::OP_MINUS>
operator-(const Matrix& a, const Matrix& b)
{
	return std::ClosureOperator, Matrix, std::ClosureOperations::OP_MINUS>(a, b);
}

template 
void operator<=(std::vector& v,
    const std::ClosureOperator, std::vector, std::ClosureOperations::OP_MULT>& c)
{
	const std::vector& b = c.r2;
	const Matrix& a = c.r1;
	assert(a.cols() == b.size());
	v.resize(a.rows());
	for (SizeType i = 0; i < a.rows(); i++) {
		T sum = 0;
		for (SizeType j = 0; j < b.size(); j++)
			sum += a(i, j) * b[j];
		v[i] = sum;
	}
}

template 
void operator<=(std::vector& v,
    const std::ClosureOperator, Matrix, std::ClosureOperations::OP_MULT>& c)
{
	const std::vector& b = c.r1;
	const Matrix& a = c.r2;
	assert(a.rows() == b.size());
	v.resize(a.cols());
	for (SizeType i = 0; i < a.cols(); i++) {
		T sum = 0;
		for (SizeType j = 0; j < b.size(); j++)
			sum += b[j] * a(j, i);
		v[i] = sum;
	}
}

template 
Matrix multiplyTransposeConjugate(const Matrix& O1, const Matrix& O2, char modifier = 'C')
{
	SizeType n = O1.rows();
	Matrix ret(n, n);
	if (modifier == 'C') {
		for (SizeType s = 0; s < n; s++)
			for (SizeType t = 0; t < n; t++)
				for (SizeType w = 0; w < n; w++)
					ret(s, t) += PsimagLite::conj(O1(w, s)) * O2(w, t);
	} else {
		for (SizeType s = 0; s < n; s++)
			for (SizeType t = 0; t < n; t++)
				for (SizeType w = 0; w < n; w++)
					ret(s, t) += O1(w, s) * O2(w, t);
	}
	return ret;
}

template 
void transposeConjugate(Matrix& m2, const Matrix& m)
{
	m2.resize(m.cols(), m.rows());
	for (SizeType i = 0; i < m2.rows(); i++)
		for (SizeType j = 0; j < m2.cols(); j++)
			m2(i, j) = PsimagLite::conj(m(j, i));
}

template 
void transpose(Matrix& m2, const Matrix& m)
{
	m2.resize(m.cols(), m.rows());
	for (SizeType i = 0; i < m2.rows(); ++i)
		for (SizeType j = 0; j < m2.cols(); ++j)
			m2(i, j) = m(j, i);
}

template 
Matrix transposeConjugate(const Matrix& A)
{
	Matrix ret(A.cols(), A.rows());
	for (SizeType i = 0; i < A.cols(); i++)
		for (SizeType j = 0; j < A.rows(); j++)
			ret(i, j) = PsimagLite::conj(A(j, i));
	return ret;
}

template 
void exp(Matrix& m)
{
	SizeType n = m.rows();
	typename Vector::Type>::Type eigs(n);
	diag(m, eigs, 'V');
	Matrix expm(n, n);
	for (SizeType i = 0; i < n; i++) {
		for (SizeType j = 0; j < n; j++) {
			T sum = 0;
			for (SizeType k = 0; k < n; k++) {
				typename Real::Type alpha = eigs[k];
				T tmp = 0.0;
				expComplexOrReal(tmp, alpha);
				sum += PsimagLite::conj(m(i, k)) * m(j, k) * tmp;
			}
			expm(i, j) = sum;
		}
	}
	m = expm;
}

template 
T norm2(const Matrix& m)
{
	T sum = 0;
	for (SizeType i = 0; i < m.rows(); i++)
		for (SizeType j = 0; j < m.cols(); j++)
			sum += m(i, j) * m(i, j);
	return sum;
}

template 
T norm2(const Matrix>& m)
{
	T sum = 0;
	for (SizeType i = 0; i < m.rows(); i++)
		for (SizeType j = 0; j < m.cols(); j++)
			sum += PsimagLite::real(PsimagLite::conj(m(i, j)) * m(i, j));
	return sum;
}

template 
T scalarProduct(const Matrix& A, const Matrix& B)
{
	return A.data_ * B.data_;
}

template 
void outerProduct(Matrix& A, const Matrix& B, const Matrix& C)
{
	SizeType ni = B.rows();
	SizeType nj = B.cols();

	A.resize(B.rows() * C.rows(), B.cols() * C.cols());

	for (SizeType i1 = 0; i1 < B.rows(); ++i1)
		for (SizeType j1 = 0; j1 < B.cols(); ++j1)
			for (SizeType i2 = 0; i2 < C.rows(); ++i2)
				for (SizeType j2 = 0; j2 < C.cols(); ++j2)
					A(i1 + i2 * ni, j1 + j2 * nj) = B(i1, j1) * C(i2, j2);
}

// closures end
template 
typename EnableIf::True, void>::Type expIpi(Matrix& A)
{
	typedef typename Real::Type RT;

	const SizeType n = A.rows();
	if (n != A.cols())
		throw RuntimeError("expIpi: expected a square matrix\n");

	typename Vector::Type eigs(n);
	diag(A, eigs, 'V');

	Matrix result(n, n);
	for (SizeType i = 0; i < n; ++i) {
		for (SizeType j = 0; j < n; ++j) {
			std::complex sum = 0;
			for (SizeType k = 0; k < n; ++k) {
				const RT arg = eigs[k] * M_PI;
				sum += PsimagLite::conj(A(i, k)) * std::complex(cos(arg), sin(arg)) * A(j, k);
			}

			result(i, j) = sum;
		}
	}

	result.swap(A); // basically, A = result
}

template 
typename EnableIf::True, void>::Type expIpi(Matrix&)
{
	throw RuntimeError("expIpi: only when using complex number\n");
}

#ifdef USE_MPI
namespace MPI
{

	template 
	typename EnableIf<
	    IsMatrixLike::True & Loki::TypeTraits::isArith,
	    void>::Type
	allReduce(SomeMatrixType& v, MPI_Op op = MPI_SUM, CommType mpiComm = MPI_COMM_WORLD)
	{
		SomeMatrixType recvbuf = v;
		MPI_Datatype datatype = MpiData::Type;
		SizeType total = v.rows() * v.cols();
		int errorCode = MPI_Allreduce(&(v(0, 0)), &(recvbuf(0, 0)), total, datatype, op, mpiComm);
		checkError(errorCode, "MPI_Allreduce", mpiComm);
		v = recvbuf;
	}

	template 
	typename EnableIf<
	    IsMatrixLike::True & IsComplexNumber::True,
	    void>::Type
	allReduce(SomeMatrixType& v, MPI_Op op = MPI_SUM, CommType mpiComm = MPI_COMM_WORLD)
	{
		SomeMatrixType recvbuf = v;
		MPI_Datatype datatype = MpiData::Type;
		SizeType total = v.rows() * v.cols();
		int errorCode = MPI_Allreduce(&(v(0, 0)), &(recvbuf(0, 0)), 2 * total, datatype, op, mpiComm);
		checkError(errorCode, "MPI_Allreduce", mpiComm);
		v = recvbuf;
	}

} // namespace MPI
#endif // USE_MPI

} // namespace PsimagLite
#endif
PsimagLite-3.06/src/MatrixNonOwned.h000066400000000000000000000035311446452427400173720ustar00rootroot00000000000000#ifndef DMRG_MATRIX_NON_OWNED_H
#define DMRG_MATRIX_NON_OWNED_H
#include "Matrix.h"

namespace PsimagLite
{

template 
struct VectorConstOrNot {
	typedef typename Vector::Type Type;
};

template 
struct VectorConstOrNot {
	typedef const typename Vector::Type Type;
};

template 
class MatrixNonOwned
{

public:

	MatrixNonOwned(SizeType nrow, SizeType ncol, typename VectorConstOrNot::Type& data, SizeType offset)
	    : nrow_(nrow)
	    , ncol_(ncol)
	    , data_(&data)
	    , offset_(offset)
	{
		check();
	}

	explicit MatrixNonOwned(
	    const PsimagLite::Matrix::Type>& m)
	    : nrow_(m.n_row())
	    , ncol_(m.n_col())
	    , data_(&(m.data_))
	    , offset_(0)
	{
		check();
	}

	explicit MatrixNonOwned(
	    PsimagLite::Matrix::Type>& m)
	    : nrow_(m.n_row())
	    , ncol_(m.n_col())
	    , data_(&(m.data_))
	    , offset_(0)
	{
		check();
	}

	const T& operator()(SizeType i, SizeType j) const
	{
		assert(i < nrow_);
		assert(j < ncol_);
		assert(offset_ + i + j * nrow_ < data_->size());
		return (*data_)[offset_ + i + j * nrow_];
	}

	T& operator()(SizeType i, SizeType j)
	{
		assert(i < nrow_);
		assert(j < ncol_);
		assert(offset_ + i + j * nrow_ < data_->size());
		return (*data_)[offset_ + i + j * nrow_];
	}

	const typename VectorConstOrNot::Type& getVector() const
	{
		assert(data_);
		return *data_;
	}

	typename VectorConstOrNot::Type& getVector()
	{
		assert(data_);
		return *data_;
	}

private:

	void check() const
	{
		assert(data_);
		assert(offset_ + nrow_ - 1 + (ncol_ - 1) * nrow_ < data_->size());
	}

	MatrixNonOwned(const MatrixNonOwned&);

	MatrixNonOwned& operator=(const MatrixNonOwned&);

	SizeType nrow_;
	SizeType ncol_;
	typename VectorConstOrNot::Type* data_;
	SizeType offset_;
};
} // namespace PsimagLite

#endif
PsimagLite-3.06/src/MemResolv.cpp000066400000000000000000000013261446452427400167220ustar00rootroot00000000000000#include "MemResolv.h"

namespace PsimagLite
{

bool operator==(const MemoryPointer& a, const MemoryPointer& b)
{
	bool b1 = (a.type == b.type);
	bool b2 = (a.length == b.length);
	bool b3 = (a.ptr == b.ptr);

	return (b1 & b2 & b3);
}

std::ostream& operator<<(std::ostream& os, const MemResolv& mresolv)
{
	os << "MemResolvs " << mresolv.vmptr_.size() << "\n";
	for (SizeType i = 0; i < mresolv.vmptr_.size(); ++i)
		mresolv.print(os, mresolv.vmptr_[i]);

	os << "MemResolv garbage: " << mresolv.garbage_.size();
	for (SizeType i = 0; i < mresolv.garbage_.size(); ++i) {
		os << reinterpret_cast(mresolv.garbage_[i]);
		os << " " << mresolv.garbageSize_[i];
	}

	os << "\n";

	return os;
}

} // namespace PsimagLite
PsimagLite-3.06/src/MemResolv.h000066400000000000000000000523131446452427400163710ustar00rootroot00000000000000#ifndef PSI_MEM_RESOLV_H
#define PSI_MEM_RESOLV_H
#include "IsClass.h"
#include "Map.h"
#include "Sort.h"
#include "Vector.h"
#include 
#include 
#include 
#include 

namespace PsimagLite
{

struct MemoryPointer {
	unsigned int type;
	unsigned int length;
	long unsigned int ptr;
}; // struct MemoryPointers

bool operator==(const MemoryPointer& a, const MemoryPointer& b);

class MemResolv
{

	typedef std::vector VectorMemoryPointerType;
	typedef std::pair PairType;
	typedef std::vector VectorPairType;
	typedef double (*RefFunctionType)(double);

public:

	enum MemoryKindEnum { MEMORY_DATA,
		MEMORY_HEAPPTR,
		MEMORY_TEXTPTR };

	static const unsigned int SIZEOF_HEAPREF = sizeof(void*);
	static const unsigned int SIZEOF_VPTR = sizeof(void*);
	static const unsigned int SIZEOF_HEAPPTR = sizeof(void*);
	static const long unsigned int LABEL_LENGTH = 128;

	template 
	MemResolv(T* ptr)
	    : intoOffset_(0)
	    , refTextPtr_(0)
	    , zeroes_(0)
	    , lenOfZeroes_(0)
	{
	}

	MemResolv(String filename, String label)
	    : intoOffset_(0)
	    , refTextPtr_(0)
	    , zeroes_(0)
	    , lenOfZeroes_(0)
	{
		if (label.length() < LABEL_LENGTH) {
			SizeType toAdd = LABEL_LENGTH - label.length();
			for (SizeType i = 0; i < toAdd; ++i)
				label.push_back(0);
		}

		String mresolvName("MemResolv::ctor():");

		std::ifstream fin(filename.c_str());
		if (!fin || fin.bad() || !fin.good())
			throw RuntimeError(mresolvName + " cannot open " + filename + "\n");

		long unsigned int lenOfLabel = 0;
		fin.read(reinterpret_cast(&lenOfLabel),
		    sizeof(lenOfLabel));
		fin.read(reinterpret_cast(&lenOfLabel),
		    sizeof(lenOfLabel));
		if (lenOfLabel != LABEL_LENGTH)
			throw RuntimeError(mresolvName + " label length error\n");
		if (lenOfLabel != label.length())
			throw RuntimeError(mresolvName + " mismatched label length\n");

		String label2;
		label2.resize(LABEL_LENGTH);
		fin.read(const_cast(label2.data()), LABEL_LENGTH);
		if (!stringEqual(label2, label))
			throw RuntimeError(mresolvName + " mismatched label");

		long unsigned int oldStart = 0;
		char* ptrOldStart = reinterpret_cast(&oldStart);
		fin.read(ptrOldStart, sizeof(oldStart));

		std::cout << "Recovered reference heap pointer ";
		std::cout << reinterpret_cast(oldStart) << "\n";

		fin.read(reinterpret_cast(&refTextPtr_),
		    sizeof(refTextPtr_));
		std::cout << "Recovered reference text pointer " << refTextPtr_
			  << "\n";

		fin.read(reinterpret_cast(&intoOffset_),
		    sizeof(intoOffset_));

		loadChunkInfo(fin);

		long unsigned int len = 0;
		char* ptrLen = reinterpret_cast(&len);
		fin.read(ptrLen, sizeof(len));
		std::cout << "MemResolv read from file len= " << len << "\n";
		unsigned char* sourcePtr = new unsigned char[len];
		garbage_.push_back(sourcePtr);
		garbageSize_.push_back(len);
		fin.read(reinterpret_cast(sourcePtr), len);
		fin.close();

		// ADJUST POINTER VALUES
		long int newStart = pointerToLui(reinterpret_cast(sourcePtr));
		long int offset = newStart - oldStart;

		adjustPointers(sourcePtr, offset);
	}

	~MemResolv()
	{
		delete[] zeroes_;
		for (SizeType i = 0; i < garbage_.size(); ++i) {
			unsigned char* ptr = garbage_[i];
			if (garbageSize_[i] > 0)
				delete[] ptr;
		}
	}

	void save(String filename, String label) const
	{
		assert(garbage_.size() > 0);

		if (label.length() < LABEL_LENGTH) {
			SizeType toAdd = LABEL_LENGTH - label.length();
			for (SizeType i = 0; i < toAdd; ++i)
				label.push_back(0);
		}

		if (label.length() != LABEL_LENGTH)
			throw RuntimeError("MemResolv::save(): label length\n");

		std::ofstream fout(filename.c_str());

		if (!fout) {
			String msg("MemResolv::save(): cannot open file ");
			throw RuntimeError(msg + filename + "\n");
		}

		long unsigned int lenOfLabel = label.length();
		assert(lenOfLabel == LABEL_LENGTH);
		fout.write(reinterpret_cast(&lenOfLabel),
		    sizeof(lenOfLabel));
		fout.write(reinterpret_cast(&lenOfLabel),
		    sizeof(lenOfLabel));
		fout.write(label.data(), lenOfLabel);

		SizeType total = 0;
		SizeType maxHoleSize = 0;
		VectorPairType offsetsForHoles;
		findSizes(total, maxHoleSize, offsetsForHoles);

		long unsigned int refPtrValue = pointerToLui(reinterpret_cast(vmptr_[0].ptr));
		adjustPointer(reinterpret_cast(&refPtrValue),
		    sizeof(refPtrValue),
		    0,
		    &offsetsForHoles);
		char* ptrRefPtr = reinterpret_cast(&refPtrValue);
		fout.write(ptrRefPtr, sizeof(refPtrValue));

		fout.write(reinterpret_cast(&refTextPtr_),
		    sizeof(refTextPtr_));
		std::cout << "Written reference text pointer " << refTextPtr_
			  << "\n";

		const char* ptrIntoPtr = reinterpret_cast(&intoOffset_);
		fout.write(ptrIntoPtr, sizeof(intoOffset_));

		updateZeroes(maxHoleSize + 1);

		saveChunkInfo(fout, offsetsForHoles);

		long unsigned int len = total;
		char* ptrLen = reinterpret_cast(&len);
		fout.write(ptrLen, sizeof(len));

		SizeType total2 = saveChunkData(fout, offsetsForHoles);
		std::cout << "Saved " << total2 << " bytes to " << filename
			  << "\n";
		fout.close();
	}

	unsigned char* get() { return garbage_[0] + intoOffset_; }

	template 
	void push(MemoryKindEnum type, unsigned int length, T* ptr, String msg = "")
	{
		MemoryPointer mptr;
		mptr.type = type;
		mptr.length = length;
		const void* vptr = reinterpret_cast(ptr);
		mptr.ptr = pointerToLui(vptr);
		if (find(vmptr_.begin(), vmptr_.end(), mptr) != vmptr_.end())
			return;

		vmptr_.push_back(mptr);
		rankVector_.push_back(mptr.ptr);

		if (msg == "")
			return;
		std::cout << "Address start " << vptr << " length "
			  << mptr.length;
		std::cout << " type=" << type << " " << msg << "\n";
	}

	unsigned char* dup()
	{
		SizeType total = 0;
		SizeType maxHoleSize = 0;
		VectorPairType offsetsForHoles;
		findSizes(total, maxHoleSize, offsetsForHoles);
		std::cout << "total = " << total
			  << " maxHoleSize= " << maxHoleSize << "\n";
		unsigned char* ptr = new unsigned char[total];
		garbage_.push_back(ptr);
		garbageSize_.push_back(total);

		updateZeroes(maxHoleSize + 1);

		deepCopy(ptr, total, offsetsForHoles);

		return ptr + intoOffset_;
	}

	template 
	typename EnableIf::value, SizeType>::Type
	memResolv(const NoClassType* c, SizeType x = sizeof(NoClassType), String msg = "")
	{
		SizeType tmp = sizeof(NoClassType);
		assert(x >= tmp);
		SizeType r = x - tmp;
		char* cPtr = (char*)c;
		updateZeroes(r + 1, 0);
		cPtr += tmp;
		memcpy(cPtr, zeroes_, r);
		tmp += r;
		push(MemResolv::MEMORY_DATA, tmp, c, msg + " fundamental type");
		return tmp;
	}

	template 
	typename EnableIf::True,
	    SizeType>::Type
	memResolv(const SomeComplexNumber*,
	    SizeType = sizeof(SomeComplexNumber),
	    String = "")
	{
		throw RuntimeError(
		    "memResolv for std::complex not implemented\n");
	}

	template 
	SizeType memResolv(const std::basic_string* c,
	    SizeType x = sizeof(std::basic_string),
	    String msg = "")
	{
		assert(x == sizeof(std::basic_string));
		SizeType total = x;
		push(MemResolv::MEMORY_HEAPPTR, x, c, msg + " string ptr");

		const long unsigned int* c2 = (const long unsigned int*)c;
		const char* c3 = (const char*)*c2;
		SizeType len = sizeof(unsigned int);
		char* ptr = const_cast(c3);
		ptr -= len;
		updateZeroes(len + 1, 0);
		memcpy(reinterpret_cast(ptr), zeroes_, len);
		ptr += len;
		len *= 3;
		ptr -= len;
		push(MemResolv::MEMORY_DATA, len, ptr, msg + " string misc");
		if (c->length() == 0)
			return total;
		push(MemResolv::MEMORY_DATA, c->length(), c3, msg + " string data");
		return total;
	}

	template 
	typename EnableIf::True, SizeType>::Type
	memResolv(const SomePairType* c, SizeType x = sizeof(SomePairType), String msg = "")
	{
		typedef typename SomePairType::first_type FirstType;
		typedef typename SomePairType::second_type SecondType;

		const FirstType* f = (const FirstType*)c;
		SizeType total = memResolv(f, sizeof(FirstType), msg + "->first");

		const char* s = (const char*)c;
		s += sizeof(FirstType*);
		const SecondType* s2 = (const SecondType*)s;
		total += memResolv(s2, sizeof(SecondType), msg + "->second");

		assert(x >= sizeof(SomePairType));
		SizeType r = x - sizeof(SomePairType);

		if (r == 0)
			return total;

		updateZeroes(r + 1, 0);
		const char* s3 = reinterpret_cast(c);
		char* ptr = const_cast(s3);
		ptr += sizeof(SomePairType);
		memcpy(reinterpret_cast(ptr), zeroes_, r);

		return total;
	}

	template 
	typename EnableIf<
	    IsVectorLike::True & !IsClass::value,
	    SizeType>::Type
	memResolv(const SomeVectorType* v, SizeType = 0, String msg = "")
	{
		typedef typename SomeVectorType::value_type SomeElementType;

		SizeType tmp = sizeof(SomeVectorType);
		push(MemResolv::MEMORY_HEAPPTR, tmp, v, msg + "vector ");
		assert(tmp = 3 * sizeof(void*)); // begin end reserve
		checkForVectorReserve(v);

		SizeType total = tmp;
		const SomeVectorType& vv = *v;

		tmp = sizeof(SomeElementType) * vv.size();
		if (tmp == 0)
			return total;

		push(MemResolv::MEMORY_DATA, tmp, &(vv[0]), msg + " vector data no class");
		// total += tmp;

		return total;
	}

	template 
	typename EnableIf<
	    IsVectorLike::True & IsClass::value,
	    SizeType>::Type
	memResolv(const SomeVectorType* v, SizeType = 0, String msg = "")
	{
		SizeType tmp = sizeof(SomeVectorType);
		assert(tmp = 3 * sizeof(void*)); // begin end reserve
		push(MemResolv::MEMORY_HEAPPTR, tmp, v, msg + " vector");
		checkForVectorReserve(v);

		SizeType total = tmp;
		const SomeVectorType& vv = *v;

		if (vv.size() == 0)
			return total;
		SizeType elementSize = sizeof(vv[0]);
		for (SizeType i = 0; i < vv.size(); ++i)
			memResolv(&vv[i], elementSize, msg);

		return total;
	}

	template 
	typename EnableIf<
	    IsVectorLike::True & !IsClass::value,
	    SizeType>::Type
	memResolvPtr(const SomeVectorType* v, SizeType = 0, String msg = "")
	{
		typedef typename SomeVectorType::value_type SomeElementType;

		SizeType tmp = sizeof(SomeVectorType);
		push(MemResolv::MEMORY_HEAPPTR, tmp, v, msg + " vector ");
		assert(tmp = 3 * sizeof(void*)); // begin end reserve
		checkForVectorReserve(v);

		SizeType total = tmp;
		const SomeVectorType& vv = *v;

		tmp = sizeof(SomeElementType) * vv.size();
		if (tmp == 0)
			return total;

		push(MemResolv::MEMORY_HEAPPTR, tmp, &(vv[0]), msg + " vector data is pointers");
		total += tmp;

		return total;
	}

	template 
	typename EnableIf::True, SizeType>::Type
	memResolv(const SomeMapType*, SizeType = 0, String = "")
	{
		throw RuntimeError("memResolv for std::map not implemented\n");
	}

	template 
	typename EnableIf::True & !IsPairLike::True & !IsMapLike::True & !IsComplexNumber::True & IsClass::value,
	    SizeType>::Type
	memResolv(const SomeClassType* c, SizeType x = 0, String msg = "")
	{
		return c->memResolv(*this, x, msg);
	}

	friend std::ostream& operator<<(std::ostream& os,
	    const MemResolv& mresolv);

private:

	template 
	void checkForVectorReserve(const SomeVectorType* vPtr) const
	{
		const long unsigned int* v = (const long unsigned int*)vPtr;
		const long unsigned int* end = (const long unsigned int*)(v + 1);
		const long unsigned int* reserve = (const long unsigned int*)(v + 2);
		if (*end != *reserve)
			std::cerr << "WARNING: std::vector has reserve\n";
	}

	void updateZeroes(SizeType x, int value = -128) const
	{
		if (lenOfZeroes_ == x)
			return;

		if (zeroes_ != 0)
			delete[] zeroes_;

		assert(x > 0);
		zeroes_ = new char[x];
		for (SizeType i = 0; i < x; ++i)
			zeroes_[i] = value;
		lenOfZeroes_ = x;
	}

	bool stringEqual(String str1, String str2) const
	{
		if (str1.length() != str2.length())
			return false;

		for (SizeType i = 0; i < str1.length(); ++i) {
			if (str1[i] == 0 && str2[i] == 0)
				break;
			if (str1[i] != str2[i])
				return false;
		}

		return true;
	}

	void print(std::ostream& os, const MemoryPointer& mp) const
	{
		os << mp.type << " " << mp.length << " " << mp.ptr << " 0x";
		std::hex(os);
		os << mp.ptr << "\n";
		std::dec(os);
	}

	void finish()
	{
		if (vmptr_.size() == 0)
			return;

		std::vector iperm(rankVector_.size());
		Sort> sort;
		sort.sort(rankVector_, iperm);
		unsigned int long oldStart = pointerToLui(reinterpret_cast(vmptr_[0].ptr));
		VectorMemoryPointerType vmptr(vmptr_.size());
		std::cout << "Chunks in order\n";
		for (SizeType i = 0; i < iperm.size(); ++i) {
			SizeType j = iperm[i];
			vmptr[i] = vmptr_[j];
			std::cout << "Entry " << vmptr[i].type << " 0x";
			std::hex(std::cout);
			std::cout << vmptr[i].ptr << " ";
			std::dec(std::cout);
			std::cout << " " << vmptr[i].length << "\n";
		}

		vmptr_ = vmptr;
		unsigned int long newStart = pointerToLui(reinterpret_cast(vmptr_[0].ptr));
		intoOffset_ = (newStart > oldStart) ? newStart - oldStart
						    : oldStart - newStart;

		SizeType total = 0;
		SizeType maxHoleSize = 0;
		VectorPairType offsetsForHoles;
		findSizes(total, maxHoleSize, offsetsForHoles);

		int long correctedIntoOffset = intoOffset_;
		int long correctedOldStart = oldStart;
		adjustPointer(
		    reinterpret_cast(&correctedOldStart),
		    sizeof(correctedOldStart),
		    0,
		    &offsetsForHoles);
		correctedIntoOffset -= oldStart;
		correctedIntoOffset += correctedOldStart;

		intoOffset_ = correctedIntoOffset;
	}

	void saveChunkInfo(std::ofstream& fout,
	    const VectorPairType& offsetsForHoles) const
	{
		long unsigned int len = vmptr_.size();
		fout.write(reinterpret_cast(&len), sizeof(len));
		for (SizeType i = 0; i < vmptr_.size(); ++i) {
			MemoryPointer mptr = vmptr_[i];
			adjustPointer(
			    reinterpret_cast(&(mptr.ptr)),
			    sizeof(mptr.ptr),
			    0,
			    &offsetsForHoles);

			fout.write(reinterpret_cast(&mptr),
			    sizeof(MemoryPointer));
		}
	}

	SizeType saveChunkData(std::ofstream& fout,
	    const VectorPairType& offsetsForHoles) const
	{
		SizeType total = 0;

		for (SizeType i = 0; i < vmptr_.size(); ++i) {
			if (i > 0) {
				long unsigned int end = vmptr_[i - 1].ptr + vmptr_[i - 1].length;
				SizeType srcHoleSize = vmptr_[i].ptr - end;
				SizeType destHoleSize = srcHoleSize % 8;

				if (lenOfZeroes_ <= destHoleSize)
					throw RuntimeError("lenZeroes\n");
				if (destHoleSize > 0) {
					fout.write(zeroes_, destHoleSize);
				}

				total += destHoleSize;
			}

			SizeType len = vmptr_[i].length;
			char* mptr = reinterpret_cast(vmptr_[i].ptr);
			char* allocated = 0;

			if (vmptr_[i].type == MEMORY_HEAPPTR) {
				allocated = new char[len];
				memcpy(allocated,
				    reinterpret_cast(vmptr_[i].ptr),
				    len);
				adjustPointer(reinterpret_cast(
						  allocated),
				    len,
				    0,
				    &offsetsForHoles);
			}

			fout.write((allocated == 0) ? mptr : allocated, len);
			total += len;
			if (allocated)
				delete[] allocated;
		}

		return total;
	}

	void loadChunkInfo(std::ifstream& fin)
	{
		long unsigned int len = 0;
		fin.read(reinterpret_cast(&len), sizeof(len));
		vmptr_.resize(len);
		for (SizeType i = 0; i < vmptr_.size(); ++i) {
			MemoryPointer* mptr = &(vmptr_[i]);
			fin.read(reinterpret_cast(mptr),
			    sizeof(MemoryPointer));
			rankVector_.push_back(mptr->ptr);
		}
	}

	void findSizes(SizeType& total, SizeType& maxHoleSize, VectorPairType& offsetsForHoles) const
	{
		maxHoleSize = 1;
		total = 0;
		if (vmptr_.size() == 0)
			return;
		long unsigned int start = vmptr_[0].ptr;
		long unsigned int end = start + vmptr_[0].length;
		total = vmptr_[0].length;
		for (SizeType i = 1; i < vmptr_.size(); ++i) {
			long unsigned int start2 = vmptr_[i].ptr;
			long unsigned int end2 = start2 + vmptr_[i].length;
			if (start2 < end)
				throw RuntimeError("findTotal end\n");

			total += vmptr_[i].length;
			long int srcHoleSize = start2 - end;
			long int destHoleSize = srcHoleSize % 8;
			long int offset = destHoleSize - srcHoleSize;
			PairType offsetForHole(start2, offset);
			offsetsForHoles.push_back(offsetForHole);
			total += destHoleSize;
			if (static_cast(destHoleSize) > maxHoleSize)
				maxHoleSize = destHoleSize;

			end = end2;
			start = start2;
		}
	}

	void deepCopy(unsigned char* ptr, SizeType total, const VectorPairType& offsetsForHoles)
	{
		if (vmptr_.size() == 0)
			return;

		long unsigned int newStart = pointerToLui(reinterpret_cast(ptr));
		long unsigned int oldStart = vmptr_[0].ptr;
		long int offset = newStart - oldStart;

		long unsigned int start = vmptr_[0].ptr;
		SizeType len = vmptr_[0].length;
		long unsigned int end = start + len;

		SizeType total2 = copyData(&ptr, 0, offset, offsetsForHoles);

		for (SizeType i = 1; i < vmptr_.size(); ++i) {
			if (total2 >= total)
				throw RuntimeError("deepCopy total2\n");
			long unsigned int start2 = vmptr_[i].ptr;
			SizeType len = vmptr_[i].length;
			long unsigned int end2 = start2 + len;
			if (start2 < end)
				throw RuntimeError("deepCopy\n");
			SizeType srcHoleSize = start2 - end;
			SizeType destHoleSize = srcHoleSize % 8;

			if (lenOfZeroes_ <= destHoleSize)
				throw RuntimeError("lenZeroes\n");
			if (destHoleSize > 0) {
				memcpy(ptr, zeroes_, destHoleSize);
			}

			ptr += destHoleSize;
			total2 += destHoleSize;

			total2 += copyData(&ptr, i, offset, offsetsForHoles);

			start = start2;
			end = end2;
		}

		if (total2 < total) {
			assert(total - total2 < lenOfZeroes_);
			memcpy(ptr, zeroes_, total - total2);
		}
	}

	SizeType copyData(unsigned char** ptr, SizeType i, long int offset, const VectorPairType& offsetsForHoles)
	{
		const void* src = reinterpret_cast(vmptr_[i].ptr);
		void* src2 = const_cast(src);
		SizeType len = vmptr_[i].length;

		memcpy(*ptr, src2, len);
		if (vmptr_[i].type == MEMORY_HEAPPTR)
			adjustPointer(*ptr, len, offset, &offsetsForHoles);
		*ptr += len;
		return len;
	}

	void adjustPointers(unsigned char* ptr, long int offset) const
	{
		/*VectorPairType offsetsForHoles(0);
		RefFunctionType f = &PsimagLite::conj;
		long int offsetText = (long int)(*f);
		std::cout< 0) {
				long unsigned int end = vmptr_[i-1].ptr +
		vmptr_[i-1].length; SizeType holeSize = vmptr_[i].ptr - end; if
		(holeSize > 0) std::cerr<<"WARNING: input file has holes\n"; ptr
		+= holeSize;
			}

			SizeType len = vmptr_[i].length;
			if (vmptr_[i].type == MEMORY_HEAPPTR)
				adjustPointer(ptr,len,offset,&offsetsForHoles);
			if (vmptr_[i].type == MEMORY_TEXTPTR)
				adjustPointer(ptr,len,offsetText,0);
			ptr += len;

		}*/
	}

	void adjustPointer(unsigned char* ptr, SizeType n, long int offset, const VectorPairType* offsetsForHoles) const
	{
		if (n < 8 || n % 8 != 0)
			throw RuntimeError("adjustPointer");

		SizeType counter = 0;

		do {
			void* p = reinterpret_cast(ptr);
			long unsigned int* ptrToLui = reinterpret_cast(ptr);
			long unsigned int value = *ptrToLui;

			if (value != 0) {
				long int correctForHoles = correctionForHoles(value, offsetsForHoles);
				long int allOffsetCorrections = correctForHoles + offset;
				value += allOffsetCorrections;
				long unsigned int* valuePtr = &value;
				memcpy(p, valuePtr, 8);
			}

			ptr += 8;
			counter += 8;
		} while (counter < n);
	}

	long int
	correctionForHoles(long unsigned int value,
	    const VectorPairType* offsetsForHolesPtr) const
	{
		if (offsetsForHolesPtr == 0)
			return 0;
		const VectorPairType& offsetsForHoles = *offsetsForHolesPtr;
		long int c = 0;
		for (SizeType i = 0; i < offsetsForHoles.size(); ++i) {
			SizeType start = offsetsForHoles[i].first;
			if (value < start)
				return c;
			c += offsetsForHoles[i].second;
		}

		return c;
	}

	long unsigned int pointerToLui(const void* ptr) const
	{
		return reinterpret_cast(ptr);
	}

	long unsigned int intoOffset_;
	long int refTextPtr_;
	mutable char* zeroes_;
	mutable SizeType lenOfZeroes_;
	VectorMemoryPointerType vmptr_;
	std::vector rankVector_;
	std::vector garbage_;
	std::vector garbageSize_;
}; // class MemResolv

std::ostream& operator<<(std::ostream& os, const MemResolv& mresolv);

template 
class ResolveFinalOrNot
{
};

template 
class ResolveFinalOrNot
{

public:

	static SizeType resolve(MemResolv& vmptr, SizeType size, const T* ptr)
	{
		SizeType tmp = sizeof(T) * size;
		vmptr.push(MemResolv::MEMORY_DATA, tmp, ptr, "pod");
		return tmp;
	}
};

template 
class ResolveFinalOrNot
{

public:

	static SizeType resolve(MemResolv& vmptr, SizeType size, const T* ptr)
	{
		SizeType tmp = 0;
		for (SizeType i = 0; i < size; ++i)
			tmp += vmptr.memResolv(&(ptr[i]));
		return tmp;
	}
};

} // namespace PsimagLite

#endif // PSI_MEM_RESOLV_H
PsimagLite-3.06/src/MemoryCpu.h000066400000000000000000000023441446452427400163770ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*!
 *
 *
 */
#ifndef MEMORY_CPU_H
#define MEMORY_CPU_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 

namespace PsimagLite
{

class MemoryCpu
{

public:

	void deallocate(void* p)
	{
		assert(p);
		free(p);
		std::ostringstream msg;
		msg << "// Freed " << p;
		std::cout << msg.str() << "\n";
		p = 0;
	}

	void* allocate(size_t x)
	{
		void* p = malloc(x);
		std::ostringstream msg;
		msg << "// Allocated starting at " << p << " " << x << " bytes";
		std::cout << msg.str() << "\n";
		return p;
	}

}; // class MemoryCpu

MemoryCpu globalMemoryCpu;
} // namespace PsimagLite

/*@}*/
#endif // MEMORY_CPU_H
PsimagLite-3.06/src/MemoryUsage.h000066400000000000000000000117161446452427400167170ustar00rootroot00000000000000/*
Copyright (c) 2009-2013-2018, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 2.]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file MemoryUsage.h
 *
 */

#ifndef MEMORY_USAGE_H
#define MEMORY_USAGE_H
#include 
#include 
#include 

namespace PsimagLite
{

class MemoryUsage
{

	static const SizeType MY_MAX_LINE = 40240;

public:

	class TimeHandle
	{

	public:

		TimeHandle()
		{
			startTime_.tv_sec = 0;
			startTime_.tv_usec = 0;
			gettimeofday(&startTime_, 0);
		}

		TimeHandle(time_t s, suseconds_t u)
		{
			startTime_.tv_sec = s;
			startTime_.tv_usec = u;
		}

		TimeHandle operator-(const TimeHandle& other) const
		{
			time_t s = startTime_.tv_sec - other.startTime_.tv_sec;
			suseconds_t u = startTime_.tv_usec - other.startTime_.tv_usec;
			return TimeHandle(s, u);
		}

		TimeHandle& operator+=(const TimeHandle& other)
		{
			startTime_.tv_sec += other.startTime_.tv_sec;
			startTime_.tv_usec += other.startTime_.tv_usec;
			return *this;
		}

		time_t seconds() const { return startTime_.tv_sec; }

		suseconds_t useconds() const { return startTime_.tv_usec; }

		double millis() const
		{
			const double tmp = startTime_.tv_usec / 1000. + startTime_.tv_sec * 1000.;
			return tmp / 1000.;
		}

	private:

		timeval startTime_;
	};

	MemoryUsage(const String& myself = "")
	    : data_("")
	    , myself_(myself)
	{
		if (myself_ == "")
			myself_ = "/proc/self/status";
		update();
	}

	void update()
	{
		std::ifstream ifp(myself_.c_str());
		if (!ifp || !ifp.good() || ifp.bad())
			return;
		char tmp[MY_MAX_LINE];
		data_ = "";
		while (!ifp.eof()) {
			ifp.getline(tmp, MY_MAX_LINE);
			data_ += String(tmp);
			data_ += String("\n");
		}

		ifp.close();
	}

	String findEntry(const String& label)
	{
		long unsigned int x = data_.find(label);
		if (x == String::npos)
			return "NOT_FOUND";

		x += label.length();
		long unsigned int y = data_.find("\n", x);
		SizeType len = y - x;
		if (y == String::npos)
			len = data_.length() - x;
		String s2 = data_.substr(x, len);
		x = 0;
		const SizeType n = s2.length();
		for (SizeType i = 0; i < n; ++i) {
			++x;
			if (s2.at(i) == ' ' || s2.at(i) == '\t')
				continue;
			else
				break;
		}

		if (x > 0)
			--x;
		len = s2.length() - x;
		return s2.substr(x, len);
	}

	TimeHandle time() const
	{
		TimeHandle nowtime;
		return nowtime - startTime_;
	}

private:

	String data_;
	String myself_;
	TimeHandle startTime_;
}; // class MemoryUsage

} // namespace PsimagLite

/*@}*/
#endif // MEMORY_USAGE_H
PsimagLite-3.06/src/MersenneTwister.cpp000066400000000000000000000022351446452427400201470ustar00rootroot00000000000000#include "MersenneTwister.h"

namespace PsimagLite
{

MersenneTwister::MersenneTwister(unsigned s)
    : index_(0)
{
	seed(s);
}

MersenneTwister::MersenneTwister(unsigned s, int rank, int)
    : index_(0)
{
	seed(s);
	int news = random();
	for (int i = 1; i < rank; ++i) {
		news = random();
	}

	seed(news);
}

void MersenneTwister::seed(unsigned s)
{
	index_ = 0;
	state_[0] = s;
	for (unsigned i = 1; i < N_; ++i) {
		unsigned tmp = state_[i - 1] ^ (state_[i - 1] >> 30);
		state_[i] = keepLast32BitMask_ & (1812433253 * (tmp + i));
	}
}

void MersenneTwister::generate()
{
	for (unsigned i = 0; i < N_; ++i) {
		unsigned y = (state_[i] & 0x80000000) + (state_[(i + 1) % N_] & 0x7fffffff);
		state_[i] = state_[(i + 397) % N_] ^ (y >> 1);
		if (y % 2 != 0)
			state_[i] ^= 2567483615;
	}
}

unsigned MersenneTwister::random()
{
	if (index_ == 0)
		generate();

	unsigned y = state_[index_];
	y ^= (y >> 11);
	y ^= (y << 07) & 2636928640;
	y ^= (y << 15) & 4022730752;
	y ^= (y >> 18);

	index_ = (index_ + 1) % N_;

	return y;
}

double MersenneTwister::operator()()
{
	unsigned r = random();
	return (static_cast(r) / keepLast32BitMask_);
}

} // namespace PsimagLite
PsimagLite-3.06/src/MersenneTwister.h000066400000000000000000000020251446452427400176110ustar00rootroot00000000000000#ifndef MERSENNETWISTER_H
#define MERSENNETWISTER_H

namespace PsimagLite
{

class MersenneTwister
{

public:

	MersenneTwister(unsigned, int, int);

	MersenneTwister(unsigned);

	void seed(unsigned);

	unsigned random();

	double operator()();

	static unsigned max() { return keepLast32BitMask_; }

private:

	static const unsigned N_ = 624;
	static const unsigned keepLast32BitMask_ = 4294967295; // 2^32 - 1
	unsigned index_;
	unsigned state_[N_];
	void generate();
};

} // namespace PsimagLite

/*  K. A. Al-Hassanieh
 *
 *  MersenneTwister generates random 32-bit unsinged integers.
 *  The constructor takes an unsigned int as a seed.
 *  The return type of random() is unsigned int. Converting the
 *  output to int can cause errors, since the returned value can
 *  be larger than the max of signed int  which is 2^16 - 1:
 *  int i = rng.random(); // causes errors
 *  instead use:
 *  unsigned i = rng.random();
 *  or
 *  size_t i = rng.random();
 *
 *  operator() returns a double between 0 and 1.
 */

#endif // MERSENNETWISTER_H
PsimagLite-3.06/src/MicroArchitecture.h000066400000000000000000000025261446452427400200750ustar00rootroot00000000000000#ifndef MICROARCHITECTURE_H
#define MICROARCHITECTURE_H

#include "AllocatorCpu.h"
#include 

namespace PsimagLite
{

class MicroArchitecture
{

public:

	MicroArchitecture()
	{
		vendorId_ = readLabel("/proc/cpuinfo", "vendor_id");
		if (vendorId_.find("Intel") != String::npos) {
			vendorId_ = "Intel";
		} else {
			if (vendorId_.find("AMD") != String::npos)
				vendorId_ = "AMD";
			else
				vendorId_ = extractOther(vendorId_);
		}
	}

	const String& vendorId() const { return vendorId_; }

private:

	static String readLabel(String file, String label)
	{
		std::ifstream fin(file.c_str());
		if (!fin || fin.bad() || !fin.good())
			return "";

		String line;
		bool flag = false;
		for (; std::getline(fin, line);) {
			if (line.find(label) != String::npos) {
				flag = true;
				break;
			}
		}

		fin.close();

		if (!flag)
			return "";
		return line;
	}

	static String extractOther(String vendorId)
	{
		std::string literal = ":";
		size_t it = vendorId.find(literal);
		if (it == String::npos)
			return "";

		SizeType index = it + 1;
		SizeType ind = index;
		SizeType total = vendorId.length();
		for (; ind < total; ++ind)
			if (vendorId[ind] != ' ' && vendorId[ind] != '\t')
				break;

		String tmp1 = vendorId.substr(ind, total - ind);
		return tmp1;
	}

	String vendorId_;
};
} // namespace PsimagLite
#endif // MICROARCHITECTURE_H
PsimagLite-3.06/src/Minimizer.h000066400000000000000000000165051446452427400164260ustar00rootroot00000000000000
/*
 */

#ifndef MINIMIZER_H
#define MINIMIZER_H

#include "Vector.h"
#include 
#include 

#ifdef USE_GSL
extern "C" {
#include 
}

namespace PsimagLite
{

template 
typename FunctionType::FieldType myFunction(const gsl_vector* v, void* params)
{
	FunctionType* ft = (FunctionType*)params;
	typename Vector::Type stdv(
	    v->data, v->data + v->size);
	return ft->operator()(stdv);
}

template 
void myDfunction(const gsl_vector* v, void* params, gsl_vector* df)
{
	FunctionType* ft = (FunctionType*)params;
	typename Vector::Type src(
	    v->data, v->data + v->size);
	typename Vector::Type dest(
	    df->data, df->data + df->size);
	ft->df(dest, src);
	for (SizeType ind = 0; ind < df->size; ++ind)
		gsl_vector_set(df, ind, dest[ind]);
}

template 
void myFdFunction(const gsl_vector* v, void* params, double* f, gsl_vector* df)
{
	*f = myFunction(v, params);
	myDfunction(v, params, df);
}

template 
class Minimizer
{

	typedef typename FunctionType::FieldType FieldType;
	typedef typename Vector::Type VectorType;
	typedef Minimizer ThisType;

public:

	enum { GSL_SUCCESS = ::GSL_SUCCESS,
		GSL_CONTINUE = ::GSL_CONTINUE };

	Minimizer(FunctionType& function, SizeType maxIter, bool verbose = false)
	    : function_(function)
	    , maxIter_(maxIter)
	    , verbose_(verbose)
	    , status_(100)
	    , gslT_(gsl_multimin_fminimizer_nmsimplex2)
	    , gslS_(gsl_multimin_fminimizer_alloc(gslT_, function_.size()))
	    , gslDt_(gsl_multimin_fdfminimizer_conjugate_fr)
	    , gslDs_(gsl_multimin_fdfminimizer_alloc(gslDt_, function_.size()))
	{
	}

	~Minimizer()
	{
		gsl_multimin_fminimizer_free(gslS_);
		gsl_multimin_fdfminimizer_free(gslDs_);
	}

	int simplex(VectorType& minVector, RealType delta = 1e-3, RealType tolerance = 1e-3)
	{
		gsl_vector* x;
		/* Starting point,  */
		x = gsl_vector_alloc(function_.size());
		for (SizeType i = 0; i < minVector.size(); i++)
			gsl_vector_set(x, i, minVector[i]);

		gsl_vector* xs;
		xs = gsl_vector_alloc(function_.size());
		for (SizeType i = 0; i < minVector.size(); i++)
			gsl_vector_set(xs, i, delta);

		gsl_multimin_function func;
		func.f = myFunction;
		func.n = function_.size();
		func.params = &function_;
		gsl_multimin_fminimizer_set(gslS_, &func, x, xs);

		SizeType iter = 0;
		RealType prevValue = 0;

		for (; iter < maxIter_; iter++) {
			status_ = gsl_multimin_fminimizer_iterate(gslS_);

			if (status_) {
				String gslError(gsl_strerror(status_));
				String msg(
				    "Minimizer::simplex(...): GSL Error: ");
				msg += gslError + "\n";
				throw RuntimeError(msg);
			}

			RealType size = gsl_multimin_fminimizer_size(gslS_);
			status_ = gsl_multimin_test_size(size, tolerance);

			if (verbose_) {
				typename Vector<
				    typename FunctionType::FieldType>::Type
				    v(gslS_->x->data, gslS_->x->data + func.n);
				RealType thisValue = function_(v);
				RealType diff = fabs(thisValue - prevValue);
				std::cerr << "simplex: " << iter << " "
					  << thisValue << " diff= " << diff;
				std::cerr << " status= " << status_
					  << " size=" << size << "\n";
				prevValue = thisValue;
			}

			if (status_ == GSL_SUCCESS)
				break;
		}

		found(minVector, gslS_->x, iter);
		gsl_vector_free(x);
		gsl_vector_free(xs);
		return iter;
	}

	int conjugateGradient(VectorType& minVector, RealType delta = 1e-3, RealType delta2 = 1e-3, RealType tolerance = 1e-3, SizeType saveEvery = 0)
	{
		gsl_vector* x;
		/* Starting point,  */
		x = gsl_vector_alloc(function_.size());
		for (SizeType i = 0; i < minVector.size(); i++)
			gsl_vector_set(x, i, minVector[i]);

		gsl_multimin_function_fdf func;
		func.f = myFunction;
		func.df = myDfunction;
		func.fdf = myFdFunction;
		func.n = function_.size();
		func.params = &function_;

		gsl_multimin_fdfminimizer_set(gslDs_, &func, x, delta, delta2);

		RealType prevValue = 0;
		SizeType iter = 0;
		for (; iter < maxIter_; iter++) {
			status_ = gsl_multimin_fdfminimizer_iterate(gslDs_);

			if (status_) {
				String gslError(gsl_strerror(status_));
				String msg("Minimizer::conjugateGradient(...): "
					   "GSL Error: ");
				if (verbose_)
					std::cerr << msg << gslError << "\n";
				return -iter;
			}

			status_ = gsl_multimin_test_gradient(gslDs_->gradient,
			    tolerance);

			if (verbose_) {
				typename Vector<
				    typename FunctionType::FieldType>::Type
				    v(gslDs_->x->data,
					gslDs_->x->data + func.n);
				RealType thisValue = function_(v);
				RealType diff = fabs(thisValue - prevValue);
				std::cerr << "conjugateGradient: " << iter
					  << " " << thisValue;
				std::cerr << " diff= " << diff;
				std::cerr << " gradientNorm= "
					  << gradientNorm(gslDs_->x);
				std::cerr << " status= " << status_ << "\n";
				prevValue = thisValue;
			}

			if (status_ == GSL_SUCCESS)
				break;

			if (saveEvery > 0 && iter % saveEvery == 0)
				printIntermediate(gslDs_->x, iter);
		}

		found(minVector, gslDs_->x, iter);
		gsl_vector_free(x);
		return iter;
	}

	int status() const { return status_; }

	String statusString() const
	{
		switch (status_) {
		case GSL_SUCCESS:
			return "GSL_SUCCESS";
			break;
		case GSL_CONTINUE:
			return "GSL_CONTINUE";
			break;
		default:
			return "UNKNOWN";
			break;
		}
	}

private:

	void found(VectorType& minVector, gsl_vector* x, SizeType iter)
	{
		for (SizeType i = 0; i < minVector.size(); i++)
			minVector[i] = gsl_vector_get(x, i);
	}

	void printIntermediate(gsl_vector* x, SizeType iter) const
	{
		std::cerr << "INTERMEDIATE " << iter << "\n";
		std::cerr << x->size << "\n";
		for (SizeType i = 0; i < x->size; i++)
			std::cerr << gsl_vector_get(x, i) << "\n";
	}

	RealType gradientNorm(const gsl_vector* v) const
	{
		gsl_vector* df = gsl_vector_alloc(function_.size());
		myDfunction(v, &function_, df);
		RealType sum = 0;
		for (SizeType i = 0; i < df->size; ++i) {
			RealType tmp = gsl_vector_get(df, i);
			sum += PsimagLite::conj(tmp) * tmp;
		}

		gsl_vector_free(df);
		return sqrt(sum);
	}

	FunctionType& function_;
	SizeType maxIter_;
	bool verbose_;
	int status_;
	const gsl_multimin_fminimizer_type* gslT_;
	gsl_multimin_fminimizer* gslS_;
	const gsl_multimin_fdfminimizer_type* gslDt_;
	gsl_multimin_fdfminimizer* gslDs_;

}; // class Minimizer
} // namespace PsimagLite

#else

namespace PsimagLite
{

template 
class Minimizer
{

	typedef typename FunctionType::FieldType FieldType;
	typedef typename Vector::Type VectorType;

public:

	enum { GSL_SUCCESS = 0,
		GSL_CONTINUE = 1 };

	Minimizer(FunctionType&, SizeType, bool = false)
	{
		String str("Minimizer needs the gsl\n");
		throw RuntimeError(str);
	}

	int simplex(VectorType&, RealType = 1e-3, RealType = 1e-3)
	{
		String str("Minimizer needs the gsl\n");
		throw RuntimeError(str);
	}

	int conjugateGradient(VectorType&, RealType = 1e-3, RealType = 1e-3, RealType = 1e-3, SizeType = 0)
	{
		String str("Minimizer needs the gsl\n");
		throw RuntimeError(str);
	}

	int status() const { return 1; }

	String statusString() const { return "Minimizer needs the gsl"; }
};

} // namespace PsimagLite
#endif

#endif // MINIMIZER_H
PsimagLite-3.06/src/Minimizer.w000066400000000000000000000073721446452427400164470ustar00rootroot00000000000000\documentclass{report}
\usepackage[T1]{fontenc}
\usepackage{bera}

\usepackage[pdftex,usenames,dvipsnames]{color}
\usepackage{listings}
\definecolor{mycode}{rgb}{0.9,0.9,1}
\lstset{language=c++,tabsize=1,basicstyle=\scriptsize,backgroundcolor=\color{mycode}}

\usepackage{hyperref}
\usepackage{fancyhdr}
\pagestyle{fancy}
\usepackage{verbatim}
\begin{document}

%\title{The Powell Class for Minimization of Functions}
%\author{G.A.}
%\maketitle

\begin{comment}
@o Minimizer.h -t
@{
/*
@i license.txt
*/
@}
\end{comment}

\section{A class to minimize a function without using Derivatives}
This requires the GNU Scientific Library, libraries and devel. headers.

Explain usage here. FIXME.

This is the structure of this file:

@o Minimizer.h -t
@{
#ifndef MINIMIZER_H
#define MINIMIZER_H

#include 
#include 
#include 
extern "C" {
#include 
}

namespace PsimagLite {
	@
	@
	@
} // namespace PsimagLite
#endif // MINIMIZER_H

@}

And this is the class here:

@d theClassHere
@{
template
class Minimizer {
	@
public:
	@
	@
	@
private:
	@
	@
}; // class Minimizer
@}


@d privateTypedefsAndConstants
@{
typedef typename FunctionType::FieldType FieldType;
typedef typename Vector::Type VectorType;
typedef Minimizer ThisType;

@}

@d privateData
@{
FunctionType& function_;
SizeType maxIter_;
const gsl_multimin_fminimizer_type *gslT_;
gsl_multimin_fminimizer *gslS_;
@}

@d constructor
@{
Minimizer(FunctionType& function,SizeType maxIter)
		: function_(function),
		  maxIter_(maxIter),
		  gslT_(gsl_multimin_fminimizer_nmsimplex2),
		  gslS_(gsl_multimin_fminimizer_alloc(gslT_,function_.size()))
{
}
@}

@d publicFunctions
@{
@
@}

@d destructor
@{
~Minimizer()
{
	gsl_multimin_fminimizer_free (gslS_);
}
@}


@d simplex
@{
int simplex(VectorType& minVector,RealType delta=1e-3,RealType tolerance=1e-3)
{
	gsl_vector *x;
	/* Starting point,  */
	x = gsl_vector_alloc (function_.size());
	for (SizeType i=0;i;
	func.n = function_.size();
	func.params = &function_;
	gsl_multimin_fminimizer_set (gslS_, &func, x, xs);

	for (SizeType iter=0;iterx,iter);
			gsl_vector_free (x);
			gsl_vector_free (xs);
			return iter;
		}
	}
	gsl_vector_free (x);
	gsl_vector_free (xs);
	return -1;
}
@}

@d privateFunctions
@{
@
@}

@d found
@{
void found(VectorType& minVector,gsl_vector* x,SizeType iter)
{
	for (SizeType i=0;i
class MockVector {
public:
	MockVector(const gsl_vector *v) : v_(v)
	{
	}
	const FieldType& operator[](SizeType i) const
	{
		return v_->data[i];
	}
	SizeType size() const { return v_->size; }
private:
	const gsl_vector *v_;
}; // class MockVector
@}

@d MyFunction
@{
template
typename FunctionType::FieldType myFunction(const gsl_vector *v, void *params)
{
	MockVector mv(v);
	FunctionType* ft = (FunctionType *)params;
	return ft->operator()(mv);
}
@}

\end{document}

PsimagLite-3.06/src/Mpi.cpp000066400000000000000000000053221446452427400155360ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file Mpi.cpp
 *
 */

#ifdef USE_MPI
#include "MpiYes.cpp"
#else
#include "MpiNo.cpp"
#endif
PsimagLite-3.06/src/Mpi.h000066400000000000000000000054761446452427400152150ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 2.]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file Mpi.h
 *
 * Consider including Concurrency.h instead of this file
 *
 */
#ifndef MPI_HEADER_H
#define MPI_HEADER_H

#ifdef USE_MPI
#include "MpiYes.h"
#else
#include "MpiNo.h"
#endif

/*@}*/
#endif
PsimagLite-3.06/src/MpiNo.cpp000066400000000000000000000007071446452427400160350ustar00rootroot00000000000000// To be included by Mpi.cpp ONLY
#include "MpiNo.h"

namespace PsimagLite
{

namespace MPI
{

	int COMM_WORLD = 0;
	int SUM = 0;

	void init(int*, char***) { }

	void finalize() { }

	SizeType commSize(CommType) { return 1; }

	SizeType commRank(CommType) { return 0; }

	int barrier(CommType) { return 0; }

	bool hasMpi() { return false; }

	void info(std::ostream&) { }

	void version(std::ostream&) { }

} // namespace MPI

} // namespace PsimagLite
PsimagLite-3.06/src/MpiNo.h000066400000000000000000000071771446452427400155120ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 2.]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file MpiNo.h
 *
 * Do NOT include this file directly, use Mpi.h instead
 *
 */
#ifndef MPINO_HEADER_H
#define MPINO_HEADER_H
#include "../loki/TypeTraits.h"
#include "Vector.h"
#include 
#include 

namespace PsimagLite
{

namespace MPI
{

	typedef int CommType;
	extern int COMM_WORLD;
	extern int SUM;

	void init(int*, char***);

	void finalize();

	bool hasMpi();

	void info(std::ostream&);

	void version(std::ostream&);

	SizeType commSize(CommType);

	SizeType commRank(CommType);

	int barrier(CommType);

	template 
	void bcast(T&, int = 0, CommType = COMM_WORLD) { }

	template 
	void recv(T&, int, int, CommType = COMM_WORLD) { }

	template 
	void send(T&, int, int, CommType = COMM_WORLD) { }

	template 
	void pointByPointGather(T&, int = 0, CommType = COMM_WORLD)
	{
	}

	template 
	void reduce(T&, int = 0, int = 0, int = 0) { }

	template 
	void allReduce(T&) { }

} // namespace MPI

} // namespace PsimagLite

/*@}*/
#endif
PsimagLite-3.06/src/MpiYes.cpp000066400000000000000000000130341446452427400162160ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/
// This file is meant to be included by Mpi.cpp ONLY
/*! \file MpiYes.cpp
 *
 */

#include "MpiYes.h"

namespace PsimagLite
{

namespace MPI
{

	CommType COMM_WORLD = MPI_COMM_WORLD;

	template <>
	const MPI_Datatype MpiData::Type = MPI_LONG;

	template <>
	const MPI_Datatype MpiData::Type = MPI_INTEGER;

	template <>
	const MPI_Datatype MpiData::Type = MPI_DOUBLE;

	template <>
	const MPI_Datatype MpiData::Type = MPI_INTEGER;

	void checkError(int errorCode, PsimagLite::String caller, CommType comm)
	{
		if (errorCode == MPI_SUCCESS)
			return;

		char errorMessage[MPI_MAX_ERROR_STRING];
		int messageLength = 0;
		MPI_Error_string(errorCode, errorMessage, &messageLength);
		std::cerr << "Error in call to " << caller << " ";
		std::cerr << errorMessage << "\n";
		MPI_Abort(comm, -1);
	}

	bool hasMpi() { return true; }

	void init(int* argc, char** argv[]) { MPI_Init(argc, argv); }

	void finalize() { MPI_Finalize(); }

	SizeType commSize(CommType mpiComm)
	{
		int tmp = 1;
		if (mpiComm != 0)
			MPI_Comm_size(mpiComm, &tmp);
		return tmp;
	}

	SizeType commRank(CommType mpiComm)
	{
		int tmp = 0;
		if (mpiComm != 0)
			MPI_Comm_rank(mpiComm, &tmp);
		return tmp;
	}

	int barrier(CommType comm) { return MPI_Barrier(comm); }

	void version(std::ostream& os)
	{
		int version = 0;
		int subversion = 0;
		int ret = MPI_Get_version(&version, &subversion);
		checkError(ret, "MPI_Get_version");

		os << "MPI version=" << version << "." << subversion << "\n";

		int resultlen = 0;
		char* versionstr = new char[MPI_MAX_LIBRARY_VERSION_STRING + 1];
		ret = MPI_Get_library_version(versionstr, &resultlen);
		checkError(ret, "MPI_Get_library_version");
		os << "MPI_Get_library_version=" << versionstr << "\n";

		delete[] versionstr;
		versionstr = nullptr;

		char* name = new char[MPI_MAX_PROCESSOR_NAME + 1];
		ret = MPI_Get_processor_name(name, &resultlen);
		checkError(ret, "MPI_Get_processor_name");
		os << "MPI_Get_processor_name=" << name << "\n";

		delete[] name;
		name = nullptr;
	}

	void info(std::ostream& os)
	{
		int nkeys = 0;
		int ret = MPI_Info_get_nkeys(MPI_INFO_ENV, &nkeys);
		checkError(ret, "MPI_Info_get_nkeys");

		if (nkeys == 0)
			return;

		char* key = new char[MPI_MAX_INFO_KEY + 1];
		char* value = new char[MPI_MAX_INFO_VAL + 1];

		for (int i = 0; i < nkeys; ++i) {
			ret = MPI_Info_get_nthkey(MPI_INFO_ENV, i, key);
			checkError(ret, "MPI_Info_get_nthkey");

			int valuelen = 0;
			int flag = 0;
			ret = MPI_Info_get_valuelen(MPI_INFO_ENV, key, &valuelen, &flag);
			checkError(ret, "MPI_Info_get_valuelen");

			if (!flag || valuelen <= 0 || valuelen >= MPI_MAX_INFO_VAL)
				continue;

			ret = MPI_Info_get(MPI_INFO_ENV, key, valuelen, value, &flag);
			checkError(ret, "MPI_Info_Get");

			os << "MPI_INFO_ENV key=" << key << " value=" << value << "\n";
		}

		delete[] key;
		key = nullptr;
		delete[] value;
		value = nullptr;
	}

} // namespace MPI

} // namespace PsimagLite
PsimagLite-3.06/src/MpiYes.h000066400000000000000000000377111446452427400156730ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 2.]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file MpiYes.h
 *
 * Do NOT include this file directly, use Mpi.h instead
 *
 */
#ifndef MPIYES_HEADER_H
#define MPIYES_HEADER_H
#include "../loki/TypeTraits.h"
#include "Vector.h"
#include 
#include 
#include 

namespace PsimagLite
{

namespace MPI
{

	typedef MPI_Comm CommType;
	extern CommType COMM_WORLD;

	template 
	struct MpiData {
		static const MPI_Datatype Type;
	};

	void checkError(int errorCode, String caller, CommType comm = COMM_WORLD);

	void init(int* argc, char** argv[]);

	void finalize();

	bool hasMpi();

	void info(std::ostream&);

	void version(std::ostream&);

	SizeType commSize(CommType mpiComm);

	SizeType commRank(CommType mpiComm);

	int barrier(CommType);

	template 
	typename EnableIf::isArith, void>::Type
	recv(NumericType& v, int source, int tag, CommType mpiComm = COMM_WORLD)
	{
		String name = "MPI_Recv";
		MPI_Datatype datatype = MpiData::Type;
		MPI_Status status;
		int errorCode = MPI_Recv(&v, 1, datatype, source, tag, mpiComm, &status);
		checkError(errorCode, name, mpiComm);
	}

	template 
	void recv(std::pair& p, int source, int tag, CommType mpiComm = COMM_WORLD)
	{
		recv(p.first, source, tag, mpiComm);
		recv(p.second, source, 2 * tag, mpiComm);
	}

	template 
	typename EnableIf<
	    IsVectorLike::True & Loki::TypeTraits::isArith,
	    void>::Type
	recv(SomeVectorType& v, int source, int tag, CommType mpiComm = COMM_WORLD)
	{
		typedef typename SomeVectorType::value_type NumericType;
		String name = "MPI_Send";
		MPI_Datatype datatype = MpiData::Type;
		MPI_Status status;
		SizeType total = v.size();
		recv(total, source, tag, mpiComm);
		if (v.size() != total)
			v.resize(total);
		int errorCode = MPI_Recv(&(v[0]), v.size(), datatype, source, tag, mpiComm, &status);
		checkError(errorCode, name, mpiComm);
	}

	template 
	typename EnableIf<
	    IsVectorLike::True & IsComplexNumber::True,
	    void>::Type
	recv(SomeVectorType& v, int source, int tag, CommType mpiComm = COMM_WORLD)
	{
		typedef typename SomeVectorType::value_type NumericType;
		String name = "MPI_Send";
		MPI_Datatype datatype = MpiData::Type;
		MPI_Status status;
		SizeType total = v.size();
		recv(total, source, tag, mpiComm);
		if (v.size() != total)
			v.resize(total);
		int errorCode = MPI_Recv(&(v[0]), 2 * v.size(), datatype, source, tag, mpiComm, &status);
		checkError(errorCode, name, mpiComm);
	}

	template 
	typename EnableIf::isArith, void>::Type
	send(NumericType& v, int dest, int tag, CommType mpiComm = COMM_WORLD)
	{
		String name = "MPI_Send";
		MPI_Datatype datatype = MpiData::Type;
		int errorCode = MPI_Send(&v, 1, datatype, dest, tag, mpiComm);
		checkError(errorCode, name, mpiComm);
	}

	template 
	void send(std::pair& p, int dest, int tag, CommType mpiComm = COMM_WORLD)
	{
		send(p.first, dest, tag, mpiComm);
		send(p.second, dest, 2 * tag, mpiComm);
	}

	template 
	typename EnableIf<
	    IsVectorLike::True & Loki::TypeTraits::isArith,
	    void>::Type
	send(SomeVectorType& v, int dest, int tag, CommType mpiComm = COMM_WORLD)
	{
		typedef typename SomeVectorType::value_type NumericType;
		String name = "MPI_Send";
		MPI_Datatype datatype = MpiData::Type;
		int total = v.size();
		send(total, dest, tag, mpiComm);
		int errorCode = MPI_Send(&(v[0]), v.size(), datatype, dest, tag, mpiComm);
		checkError(errorCode, name, mpiComm);
	}

	template 
	typename EnableIf<
	    IsVectorLike::True & IsComplexNumber::True,
	    void>::Type
	send(SomeVectorType& v, int dest, int tag, CommType mpiComm = COMM_WORLD)
	{
		typedef typename SomeVectorType::value_type NumericType;
		String name = "MPI_Send";
		MPI_Datatype datatype = MpiData::Type;
		int total = v.size();
		send(total, dest, tag, mpiComm);
		int errorCode = MPI_Send(&(v[0]), 2 * v.size(), datatype, dest, tag, mpiComm);
		checkError(errorCode, name, mpiComm);
	}

	template 
	typename EnableIf<
	    IsVectorLike::True&(
		Loki::TypeTraits::isArith | IsVectorLike::True),
	    void>::Type
	pointByPointGather(SomeVectorType& v, int root = 0, CommType mpiComm = COMM_WORLD)
	{
		typedef typename SomeVectorType::value_type NumericType;
		int mpiRank = MPI::commRank(mpiComm);
		int nprocs = MPI::commSize(mpiComm);
		SizeType blockSize = static_cast(v.size() / nprocs);
		if (v.size() % nprocs != 0)
			blockSize++;

		if (mpiRank != root) {
			for (SizeType p = 0; p < blockSize; p++) {
				SizeType taskNumber = mpiRank * blockSize + p;
				if (taskNumber >= v.size())
					break;
				MPI::send(v[taskNumber], 0, taskNumber);
			}
		} else {
			for (int r = 0; r < nprocs; r++) {
				if (r == root)
					continue;
				for (SizeType p = 0; p < blockSize; p++) {
					SizeType taskNumber = r * blockSize + p;
					if (taskNumber >= v.size())
						break;
					NumericType value;
					MPI::recv(value, r, taskNumber);
					v[taskNumber] = value;
				}
			}
		}
	}

	template 
	typename EnableIf<
	    IsVectorLike::True & !IsVectorLike::True & !Loki::TypeTraits::isArith & !IsPairLike::True,
	    void>::Type
	pointByPointGather(SomeVectorType& v, int root = 0, CommType mpiComm = COMM_WORLD)
	{
		int mpiRank = MPI::commRank(mpiComm);
		int nprocs = MPI::commSize(mpiComm);
		SizeType blockSize = static_cast(v.size() / nprocs);
		if (v.size() % nprocs != 0)
			blockSize++;

		if (mpiRank != root) {
			for (SizeType p = 0; p < blockSize; p++) {
				SizeType taskNumber = mpiRank * blockSize + p;
				if (taskNumber >= v.size())
					break;
				v[taskNumber].send(0, taskNumber, mpiComm);
			}
		} else {
			for (int r = 0; r < nprocs; r++) {
				if (r == root)
					continue;
				for (SizeType p = 0; p < blockSize; p++) {
					SizeType taskNumber = r * blockSize + p;
					if (taskNumber >= v.size())
						break;
					v[taskNumber].recv(r, taskNumber, mpiComm);
				}
			}
		}
	}

	template 
	typename EnableIf::True & IsPairLike::True,
	    void>::Type
	pointByPointGather(SomeVectorType& v, int root = 0, CommType mpiComm = COMM_WORLD)
	{
		int mpiRank = MPI::commRank(mpiComm);
		int nprocs = MPI::commSize(mpiComm);
		SizeType blockSize = static_cast(v.size() / nprocs);
		if (v.size() % nprocs != 0)
			blockSize++;

		if (mpiRank != root) {
			for (SizeType p = 0; p < blockSize; p++) {
				SizeType taskNumber = mpiRank * blockSize + p;
				if (taskNumber >= v.size())
					break;
				send(v[taskNumber], 0, taskNumber, mpiComm);
			}
		} else {
			for (int r = 0; r < nprocs; r++) {
				if (r == root)
					continue;
				for (SizeType p = 0; p < blockSize; p++) {
					SizeType taskNumber = r * blockSize + p;
					if (taskNumber >= v.size())
						break;
					recv(v[taskNumber], r, taskNumber, mpiComm);
				}
			}
		}
	}

	template 
	typename EnableIf<
	    IsVectorLike::True & IsVectorLike::True & Loki::TypeTraits::isArith,
	    void>::Type
	bcast(SomeVectorType& v, int root = 0, CommType mpiComm = COMM_WORLD)
	{
		typedef typename SomeVectorType::value_type DataType;
		String name = "MPI_Bcast";
		for (SizeType i = 0; i < v.size(); i++) {
			DataType& vv = v[i];
			int total = vv.size();
			int errorCode = MPI_Bcast(&total, 1, MPI_INTEGER, root, mpiComm);
			checkError(errorCode, name, mpiComm);
			if (static_cast(total) != vv.size())
				vv.resize(total);
			MPI_Datatype datatype = MpiData::Type;
			errorCode = MPI_Bcast(&(vv[0]), vv.size(), datatype, root, mpiComm);
			checkError(errorCode, name, mpiComm);
		}
	}

	template 
	typename EnableIf::isArith, void>::Type
	bcast(NumericType& v, int root = 0, CommType mpiComm = COMM_WORLD)
	{
		MPI_Datatype datatype = MpiData::Type;
		int errorCode = MPI_Bcast(&v, 1, datatype, root, mpiComm);
		checkError(errorCode, "MPI_Bcast", mpiComm);
	}

	template 
	typename EnableIf<
	    IsVectorLike::True & Loki::TypeTraits::isArith,
	    void>::Type
	bcast(SomeVectorType& v, int root = 0, CommType mpiComm = COMM_WORLD)
	{
		SizeType total = v.size();
		bcast(total, root, mpiComm);
		if (total != v.size())
			v.resize(total, 0);
		MPI_Datatype datatype = MpiData::Type;
		int errorCode = MPI_Bcast(&(v[0]), v.size(), datatype, root, mpiComm);
		checkError(errorCode, "MPI_Bcast", mpiComm);
	}

	template 
	typename EnableIf<
	    IsVectorLike::True & IsComplexNumber::True,
	    void>::Type
	bcast(SomeVectorType& v, int root = 0, CommType mpiComm = COMM_WORLD)
	{
		MPI_Datatype datatype = MpiData::Type;
		int errorCode = MPI_Bcast(&(v[0]), 2 * v.size(), datatype, root, mpiComm);
		checkError(errorCode, "MPI_Bcast", mpiComm);
	}

	template 
	typename EnableIf::isArith & Loki::TypeTraits::isArith,
	    void>::Type
	bcast(std::pair& p, int root = 0, CommType mpiComm = COMM_WORLD)
	{
		T1 t1 = p.first;
		MPI_Datatype datatype = MpiData::Type;
		int errorCode = MPI_Bcast(&t1, 1, datatype, root, mpiComm);

		T2 t2 = p.second;
		MPI_Datatype datatype2 = MpiData::Type;
		errorCode = MPI_Bcast(&t2, 1, datatype2, root, mpiComm);

		p = std::pair(t1, t2);
	}

	template 
	typename EnableIf<
	    IsVectorLike::True & !IsVectorLike::True & !Loki::TypeTraits::isArith & !IsComplexNumber::True,
	    void>::Type
	bcast(SomeVectorType& v, int root = 0, CommType mpiComm = COMM_WORLD)
	{
		for (SizeType i = 0; i < v.size(); i++) {
			v[i].bcast(root, mpiComm);
		}
	}

	template 
	typename EnableIf<
	    IsVectorLike::True & Loki::TypeTraits::isArith,
	    void>::Type
	reduce(SomeVectorType& v, MPI_Op op = MPI_SUM, int root = 0, CommType mpiComm = COMM_WORLD)
	{
		SomeVectorType w(v.size());
		MPI_Datatype datatype = MpiData::Type;
		int errorCode = (mpiComm == 0)
		    ? MPI_SUCCESS
		    : MPI_Reduce(&(v[0]), &(w[0]), v.size(), datatype, op, root, mpiComm);
		checkError(errorCode, "MPI_Reduce", mpiComm);

		if (mpiComm && commRank(mpiComm) == static_cast(root))
			v = w;
	}

	template 
	typename EnableIf<
	    IsVectorLike::True & IsComplexNumber::True,
	    void>::Type
	reduce(SomeVectorType& v, MPI_Op op = MPI_SUM, int root = 0, CommType mpiComm = COMM_WORLD)
	{
		SomeVectorType w(v.size());
		MPI_Datatype datatype = MpiData::Type;
		int errorCode = (mpiComm == 0)
		    ? MPI_SUCCESS
		    : MPI_Reduce(&(v[0]), &(w[0]), 2 * v.size(), datatype, op, root, mpiComm);
		checkError(errorCode, "MPI_Reduce", mpiComm);

		if (mpiComm && commRank(mpiComm) == static_cast(root))
			v = w;
	}

	template 
	typename EnableIf<
	    IsVectorLike::True & Loki::TypeTraits::isArith,
	    void>::Type
	allReduce(SomeVectorType& v, MPI_Op op = MPI_SUM, CommType mpiComm = COMM_WORLD)
	{
		SomeVectorType recvbuf = v;
		MPI_Datatype datatype = MpiData::Type;
		int errorCode = MPI_Allreduce(&(v[0]), &(recvbuf[0]), v.size(), datatype, op, mpiComm);
		checkError(errorCode, "MPI_Allreduce", mpiComm);
		v = recvbuf;
	}

	template 
	typename EnableIf<
	    IsVectorLike::True & IsComplexNumber::True,
	    void>::Type
	allReduce(SomeVectorType& v, MPI_Op op = MPI_SUM, CommType mpiComm = COMM_WORLD)
	{
		SomeVectorType recvbuf = v;
		MPI_Datatype datatype = MpiData::Type;
		int errorCode = MPI_Allreduce(&(v[0]), &(recvbuf[0]), 2 * v.size(), datatype, op, mpiComm);
		checkError(errorCode, "MPI_Allreduce", mpiComm);
		v = recvbuf;
	}

	template 
	typename EnableIf::isArith, void>::Type
	allReduce(NumericType& v, MPI_Op op = MPI_SUM, CommType mpiComm = COMM_WORLD)
	{
		int result = 0;
		MPI_Datatype datatype = MpiData::Type;
		int errorCode = MPI_Allreduce(&v, &result, 1, datatype, op, mpiComm);
		checkError(errorCode, "MPI_Allreduce", mpiComm);
		v = result;
	}

} // namespace MPI

} // namespace PsimagLite

/*@}*/
#endif
PsimagLite-3.06/src/NoPthreads.h000066400000000000000000000065071446452427400165330ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/

/** \ingroup PsimagLite */
/*@{*/

/*! \file NoPthreads.h
 *
 *  If you want to say no to pthreads
 *
 */
#ifndef NO_PTHREADS_HEADER_H
#define NO_PTHREADS_HEADER_H

#include 
#include 

namespace PsimagLite
{
template 
class NoPthreads
{

public:

	NoPthreads(SizeType npthreads = 1, int = 0)
	{
		std::cerr
		    << "NoPthreads is deprecated, please use NoPthreadsNg\n";
		assert(npthreads == 1);
	}

	void loopCreate(SizeType total, PthreadFunctionHolderType& pfh)
	{
		pfh.thread_function_(0, total, total, 0);
	}

	String name() const { return "nopthreads"; }

	SizeType threads() const { return 1; }

	SizeType mpiProcs() const { return 1; }

}; // NoPthreads
} // namespace PsimagLite
/*@}*/
#endif
PsimagLite-3.06/src/NoPthreadsNg.h000066400000000000000000000105531446452427400170140ustar00rootroot00000000000000/*
Copyright (c) 2009-2017, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

---------------------------------------------------------------
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

---------------------------------------------------------------

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file NoPthreadsNg .h
 *
 *  A C++ NoPthreadsNg class that implements the Concurrency interface
 *
 */
#ifndef PSI_NOPTHREADS_NG_H
#define PSI_NOPTHREADS_NG_H
#include "CodeSectionParams.h"
#include "LoadBalancerDefault.h"

namespace PsimagLite
{

template 
class NoPthreadsNg
{

public:

	typedef LoadBalancerDefault::VectorSizeType VectorSizeType;

	NoPthreadsNg(const CodeSectionParams& cs)
	{
		if (cs.npthreads != 1)
			throw PsimagLite::RuntimeError(
			    "NoPthreadsNg: ctor with threads != 1\n");
	}

	bool affinities() const { return false; }

	size_t stackSize() const { return 0; }

	// no weights, no balancer ==> create weights, set all weigths to 1,
	// delegate
	void loopCreate(PthreadFunctionHolderType& pfh)
	{
		LoadBalancerType* loadBalancer = new LoadBalancerType(pfh.tasks(), 1);
		loopCreate(pfh, *loadBalancer);
		delete loadBalancer;
		loadBalancer = 0;
	}

	// weights, no balancer ==> create balancer with weights ==> delegate
	void loopCreate(PthreadFunctionHolderType& pfh,
	    const VectorSizeType& weights)
	{
		LoadBalancerType* loadBalancer = new LoadBalancerType(weights, 1);
		loopCreate(pfh, *loadBalancer);
		delete loadBalancer;
		loadBalancer = 0;
	}

	// balancer (includes weights)
	void loopCreate(PthreadFunctionHolderType& pfh,
	    const LoadBalancerType&)
	{
		SizeType ntasks = pfh.tasks();
		for (SizeType taskNumber = 0; taskNumber < ntasks;
		     ++taskNumber) {
			pfh.doTask(taskNumber, 0);
		}
	}

	String name() const { return "NoPthreadsNg"; }

	SizeType threads() const { return 1; }

	SizeType mpiProcs() const { return 1; }

	void setAffinities(bool) { }
}; // NoPthreadsNg class

} // namespace PsimagLite

/*@}*/
#endif
PsimagLite-3.06/src/OneOperatorSpec.h000066400000000000000000000050211446452427400175220ustar00rootroot00000000000000#ifndef ONEOPERATORSPEC_H
#define ONEOPERATORSPEC_H
#include "PsimagLite.h"
#include "Vector.h"
#include 

namespace PsimagLite
{
struct OneOperatorSpec {

	OneOperatorSpec(PsimagLite::String label_)
	    : dof(0)
	    , label(label_)
	    , transpose(false)
	{
		SizeType lastIndex = label.length();
		if (lastIndex > 0)
			lastIndex--;
		if (label[lastIndex] == '\'') {
			label = label.substr(0, lastIndex);
			transpose = true;
		}

		label_ = label;

		SizeType i = 0;
		for (; i < label.length(); ++i) {
			if (label[i] == '?')
				break;
		}

		if (i == label.length())
			return;

		if (i + 1 == label.length())
			err("WRONG op. spec. " + label_ + ", nothing after ?\n");

		label = label_.substr(0, i);
		const String numericString = label_.substr(i + 1, label_.length());
		if (!isAnInteger(numericString)) {
			throw RuntimeError("FATAL: Syntax Error: The label " + label + " must be followed by an integer " + "and not " + numericString + "\n");
		}

		dof = atoi(numericString.c_str());
	}

	struct SiteSplit {

		SiteSplit(bool hasSiteString_, String root_, String siteString_)
		    : hasSiteString(hasSiteString_)
		    , root(root_)
		    , siteString(siteString_)
		{
		}

		bool hasSiteString;
		String root;
		String siteString;
	};

	static SiteSplit extractSiteIfAny(PsimagLite::String name,
	    const char cBegin = '[',
	    const char cEnd = ']')
	{
		int firstIndex = -1;
		int lastIndex = -1;
		for (SizeType i = 0; i < name.length(); ++i) {
			if (name[i] == cBegin) {
				firstIndex = i;
				continue;
			}

			if (name[i] == cEnd) {
				lastIndex = i;
				continue;
			}
		}

		if (firstIndex < 0 && lastIndex < 0)
			return SiteSplit(false, name, "");

		bool b1 = (firstIndex < 0 && lastIndex >= 0);
		bool b2 = (firstIndex >= 0 && lastIndex < 0);
		if (b1 || b2)
			err(name + " has unmatched " + cBegin + " or " + cEnd + "\n");

		String str = name.substr(0, firstIndex);
		str += name.substr(lastIndex + 1, name.length() - lastIndex);
		String siteString = name.substr(firstIndex + 1, lastIndex - firstIndex - 1);
		return SiteSplit(true, str, siteString);
	}

	static bool isNonNegativeInteger(const String& s)
	{
		return !s.empty() && std::find_if(s.begin(), s.end(), [](char c) {
			return !std::isdigit(c);
		}) == s.end();
	}

	static SizeType strToNumberOrFail(String s)
	{
		if (!isNonNegativeInteger(s))
			err("string " + s + " is not a NonNegativeInteger\n");
		return atoi(s.c_str());
	}

	SizeType dof;
	String label;
	bool transpose;
}; // struct OneOperatorSpec

} // namespace PsimagLite
#endif // ONEOPERATORSPEC_H
PsimagLite-3.06/src/Optional.h000066400000000000000000000005701446452427400162430ustar00rootroot00000000000000#ifndef PSI_OPTIONAL_H
#define PSI_OPTIONAL_H

#include 

namespace PsimagLite
{
template 
class Optional
{

public:

	Optional(T& t)
	    : t_(&t)
	{
	}

	Optional(int)
	    : t_(0)
	{
	}

	bool nonNull() const { return (t_); }

	T& operator()()
	{
		assert(t_);
		return *t_;
	}

private:

	T* t_;
};
} // namespace PsimagLite

#endif // PSI_OPTIONAL_H
PsimagLite-3.06/src/Options.h000066400000000000000000000105061446452427400161110ustar00rootroot00000000000000/*
Copyright (c) 2012 , UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************


*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file Options.h
 *
 *  Options lines
 */

#ifndef OPTIONS_HEADER_H
#define OPTIONS_HEADER_H

#include "PsimagLite.h"
#include "Vector.h"
#include 
#include 
#include 
#include 

namespace PsimagLite
{

class Options
{

public:

	class Writeable
	{

		typedef Vector::Type VectorStringType;

	public:

		enum { DISABLED,
			PERMISSIVE,
			STRICT };

		Writeable(VectorStringType& registeredOptions, SizeType mode)
		    : registeredOptions_(registeredOptions)
		    , mode_(mode)
		{
		}

		void set(Vector::Type& optsThatAreSet, String opts)
		{
			if (mode_ == DISABLED)
				return;
			split(optsThatAreSet, opts, ",");
			for (SizeType i = 0; i < optsThatAreSet.size(); i++) {
				bool b = (find(registeredOptions_.begin(),
					      registeredOptions_.end(),
					      optsThatAreSet[i])
				    == registeredOptions_.end());
				if (!b)
					continue;

				String s(__FILE__);
				s += ": Unknown option " + optsThatAreSet[i] + "\n";
				if (mode_ == PERMISSIVE)
					std::cerr << " *** WARNING **: " << s;
				if (mode_ == STRICT)
					throw RuntimeError(s.c_str());
			}
		}

	private:

		Vector::Type registeredOptions_;
		SizeType mode_;
	}; // class Writeable

	class Readable
	{

	public:

		Readable(Writeable& optsWrite, const String& optsString)
		{
			optsWrite.set(optsThatAreSet_, optsString);
		}

		bool isSet(const String& thisOption) const
		{
			bool b = (find(optsThatAreSet_.begin(),
				      optsThatAreSet_.end(),
				      thisOption)
			    == optsThatAreSet_.end());
			return (!b);
		}

	private:

		Vector::Type optsThatAreSet_;

	}; // class Readable

}; // class OptionsWriteable
} // namespace PsimagLite
/*@}*/
#endif // OPTIONS_HEADER_H
PsimagLite-3.06/src/PackIndices.h000066400000000000000000000065731446452427400166440ustar00rootroot00000000000000/*
Copyright (c) 2009 , UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/

/** \ingroup PsimagLite */
/*@{*/

/*! \file PackIndices.h
 *
 * PAcking and unpacking of indices
 */

#ifndef PACK_INDICES_H
#define PACK_INDICES_H
#include 

namespace PsimagLite
{
class PackIndices
{

public:

	PackIndices(SizeType n)
	    : n_(n)
	{
	}

	//! given ind and n, get x and y such that ind = x + y*n
	void unpack(SizeType& x, SizeType& y, SizeType ind) const
	{
		// y  = ind/n;
		// x = ind - y*n;
		// x= ind % n;
		div_t q = PsimagLite::div(ind, n_);
		y = q.quot;
		x = q.rem;
	}

	SizeType pack(SizeType x0, SizeType x1, const Vector::Type& permutationInverse) const
	{
		assert(x0 + n_ * x1 < permutationInverse.size());
		return permutationInverse[x0 + n_ * x1];
	}

private:

	SizeType n_;
}; // class PackIndices
} // namespace PsimagLite

/*@}*/
#endif // PACK_INDICES_H
PsimagLite-3.06/src/Parallelizer.h000066400000000000000000000100731446452427400171030ustar00rootroot00000000000000/*
Copyright (c) 2009-2017, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

-----------------------------------------------------------
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

-----------------------------------------------------------

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file Parallelizer.h
 *
 */
#ifndef PARALLELIZER_H
#define PARALLELIZER_H
#include "CodeSectionParams.h"
#include "Concurrency.h"
#include "Map.h"
#include "Vector.h"
#include 

#define ActualPthreadsName PthreadsNg
#define ActualPthreadsN() "PthreadsNg.h"
#define ActualNoPthreadsName NoPthreadsNg
#define ActualNoPthreadsN() "NoPthreadsNg.h"

#ifdef USE_PTHREADS

#include ActualPthreadsN()

#else

#include ActualNoPthreadsN()

#endif // USE_PTHREADS

namespace PsimagLite
{
template 
class Parallelizer

#ifdef USE_PTHREADS

    : public ActualPthreadsName
{
	typedef ActualPthreadsName BaseType;

#else
    : public ActualNoPthreadsName
{
	typedef ActualNoPthreadsName BaseType;
#endif

public:

	Parallelizer(const CodeSectionParams& cs)
	    : BaseType(cs)
	{
	}

	Parallelizer(String codeSectionParams)
	    : BaseType(codeSectionParamss_[codeSectionParams])
	{
	}

	static bool exists(String name)
	{
		return (codeSectionParamss_.find(name) != codeSectionParamss_.end());
	}

	static void push(String name, const CodeSectionParams& cs)
	{
		codeSectionParamss_[name] = cs;
	}

	static void clear() { codeSectionParamss_.clear(); }

private:

	static Map::Type codeSectionParamss_;
};
} // namespace PsimagLite

/*@}*/
#endif
PsimagLite-3.06/src/Parallelizer2.h000066400000000000000000000004341446452427400171650ustar00rootroot00000000000000#ifndef PARALLELIZER2_H
#define PARALLELIZER2_H
#include "Concurrency.h"
#include "Vector.h"

#ifdef USE_PTHREADS
#include "Parallelizer2Pthread.h"
#else

#ifdef _OPENMP
#include "Parallelizer2OpenMP.h"
#else
#include "Parallelizer2Serial.h"
#endif

#endif

#endif // PARALLELIZER2_H
PsimagLite-3.06/src/Parallelizer2OpenMP.h000066400000000000000000000014131446452427400202420ustar00rootroot00000000000000#ifndef PARALLELIZER2OPENMP_H
#define PARALLELIZER2OPENMP_H
#include "CodeSectionParams.h"
#include "Vector.h"
#include 

namespace PsimagLite
{

template 
class Parallelizer2
{

public:

	Parallelizer2(const CodeSectionParams& codeParams)
	    : threads_(codeParams.npthreads)
	{
		omp_set_num_threads(codeParams.npthreads);
	}

	template 
	void parallelFor(SizeType start, SizeType end, const SomeLambdaType& lambda)
	{
#pragma omp parallel for
		for (SizeType i = start; i < end; ++i)
			lambda(i, omp_get_thread_num());
	}

	SizeType numberOfThreads() const { return omp_get_num_threads(); }

	String name() const { return "openmp"; }

private:

	SizeType threads_;
};
} // namespace PsimagLite
#endif // PARALLELIZER2OPENMP_H
PsimagLite-3.06/src/Parallelizer2Pthread.h000066400000000000000000000114531446452427400205000ustar00rootroot00000000000000#ifndef PARALLELIZER2PTHREAD_H
#define PARALLELIZER2PTHREAD_H
#include "CodeSectionParams.h"
#include "LoadBalancerDefault.h"
#include "TypeToString.h"
#include "Vector.h"
#include 
#include 
#include 
#include 
#include 

#ifdef __linux__
#include 
#include 
#endif

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#ifdef _GNU_SOURCE
#include 
#include 
#endif

template 
struct PthreadFunctionStruct2 {
	PthreadFunctionStruct2()
	    : pfh(0)
	    , loadBalancer(0)
	    , threadNum(0)
	    , nthreads(0)
	    , start(0)
	    , end(0)
	    , cpu(0)
	{
	}

	const SomeLambdaType* pfh;
	const LoadBalancerType* loadBalancer;
	int threadNum;
	SizeType nthreads;
	SizeType start;
	SizeType end;
	SizeType cpu;
};

template 
void* thread_function_wrapper2(void* dummyPtr)
{
	PthreadFunctionStruct2* pfs = static_cast<
	    PthreadFunctionStruct2*>(
	    dummyPtr);

	const SomeLambdaType* pfh = pfs->pfh;

	int s = 0;
#ifdef __linux__
	s = sched_getcpu();
#endif
	if (s >= 0)
		pfs->cpu = s;

	SizeType blockSize = pfs->loadBalancer->blockSize(pfs->threadNum);

	for (SizeType p = 0; p < blockSize; ++p) {
		SizeType taskNumber = pfs->loadBalancer->taskNumber(pfs->threadNum, p);
		if (taskNumber + pfs->start >= pfs->end)
			break;
		(*pfh)(taskNumber + pfs->start, pfs->threadNum);
	}

	int retval = 0;
	pthread_exit(static_cast(&retval));
	return 0;
}

namespace PsimagLite
{

template 
class Parallelizer2
{

public:

	typedef LoadBalancerDefault::VectorSizeType VectorSizeType;

	Parallelizer2(const CodeSectionParams& codeParams)
	    : nthreads_(codeParams.npthreads)
	    , stackSize_(codeParams.stackSize)
	{
	}

	SizeType numberOfThreads() const { return nthreads_; }

	String name() const { return "pthread"; }

	// no weights, no balancer ==> create weights, set all weigths to 1,
	// delegate
	template 
	void parallelFor(SizeType start, SizeType end, const SomeLambdaType& lambda)
	{
		LoadBalancerType* loadBalancer = new LoadBalancerType(end - start, nthreads_);
		parallelFor(start, end, lambda, *loadBalancer);
		delete loadBalancer;
		loadBalancer = 0;
	}

	// weights, no balancer ==> create balancer with weights ==> delegate
	template 
	void parallelFor(SizeType start, SizeType end, const SomeLambdaType& lambda, const VectorSizeType& weights)
	{
		LoadBalancerType* loadBalancer = new LoadBalancerType(weights.size(), nthreads_);
		loadBalancer->setWeights(weights);
		parallelFor(start, end, lambda, *loadBalancer);
		delete loadBalancer;
		loadBalancer = 0;
	}

	template 
	void parallelFor(SizeType start, SizeType end, const SomeLambdaType& lambda, const LoadBalancerType& loadBalancer)
	{
		PthreadFunctionStruct2* pfs = new PthreadFunctionStruct2[nthreads_];
		pthread_t* thread_id = new pthread_t[nthreads_];
		pthread_attr_t** attr = new pthread_attr_t*[nthreads_];

		for (SizeType j = 0; j < nthreads_; ++j) {
			pfs[j].pfh = λ
			pfs[j].loadBalancer = &loadBalancer;
			pfs[j].threadNum = j;
			pfs[j].start = start;
			pfs[j].end = end;
			pfs[j].nthreads = nthreads_;

			attr[j] = new pthread_attr_t;
			int ret = (stackSize_ > 0)
			    ? pthread_attr_setstacksize(attr[j], stackSize_)
			    : 0;
			if (ret != 0) {
				std::cerr << __FILE__;
				std::cerr << "\tpthread_attr_setstacksize() "
					     "has returned non-zero "
					  << ret << "\n";
				std::cerr
				    << "\tIt is possible (but no certain) that "
				       "the following error";
				std::cerr << "\thappened.\n";
				std::cerr
				    << "\tEINVAL The stack size is less than ";
				std::cerr
				    << "PTHREAD_STACK_MIN (16384) bytes.\n";
				std::cerr << "\tI will ignore this error and "
					     "let you continue\n";
			}

			ret = pthread_attr_init(attr[j]);
			checkForError(ret);

			ret = pthread_create(
			    &thread_id[j], attr[j], thread_function_wrapper2, &pfs[j]);
			checkForError(ret);
		}

		for (SizeType j = 0; j < nthreads_; ++j)
			pthread_join(thread_id[j], 0);
		for (SizeType j = 0; j < nthreads_; ++j) {
			int ret = pthread_attr_destroy(attr[j]);
			checkForError(ret);
			delete attr[j];
			attr[j] = 0;
		}

		delete[] attr;
		delete[] thread_id;
		delete[] pfs;
	}

private:

	void checkForError(int ret) const
	{
		if (ret == 0)
			return;
		std::cerr << "PthreadsNg ERROR: " << strerror(ret) << "\n";
	}

	SizeType nthreads_;
	size_t stackSize_;
};
} // namespace PsimagLite
#endif // PARALLELIZER2PTHREAD_H
PsimagLite-3.06/src/Parallelizer2Serial.h000066400000000000000000000012601446452427400203230ustar00rootroot00000000000000#ifndef PARALLELIZER2SERIAL_H
#define PARALLELIZER2SERIAL_H
#include "CodeSectionParams.h"
#include "Vector.h"

namespace PsimagLite
{

template 
class Parallelizer2
{

public:

	Parallelizer2(const CodeSectionParams& codeParams)
	{
		if (codeParams.npthreads != 1)
			throw RuntimeError(
			    "Please compile with -DUSE_PTHREADS\n");
	}

	template 
	void parallelFor(SizeType start, SizeType end, const SomeLambdaType& lambda)
	{
		for (SizeType i = start; i < end; ++i)
			lambda(i, 0);
	}

	SizeType numberOfThreads() const { return 1; }

	String name() const { return "serial"; }
};
} // namespace PsimagLite
#endif // PARALLELIZER2SERIAL_H
PsimagLite-3.06/src/ParametersForSolver.h000066400000000000000000000136771446452427400204370ustar00rootroot00000000000000/*
Copyright (c) 2009-2011, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/

/** \ingroup PsimagLite */
/*@{*/

/*! \file ParametersForSolver.h
 *
 * Parameters to be able to use LanczosSolver and ChebyshevSolver together
 *
 * Note: This is a struct: Add no functions except ctor/dtor!
 */

#ifndef PARAMETERS_FOR_SOLVER_H
#define PARAMETERS_FOR_SOLVER_H
#include "Matrix.h"
#include "ProgressIndicator.h"
#include "Random48.h"
#include "TridiagonalMatrix.h"
#include "TypeToString.h"
#include "Vector.h"

namespace PsimagLite
{

template 
struct ParametersForSolver {

	typedef RealType_ RealType;

	static const SizeType MaxLanczosSteps = 1000000; // max number of internal Lanczos steps
	static const SizeType LanczosSteps = 200; // max number of external Lanczos steps

	ParametersForSolver()
	    : steps(LanczosSteps)
	    , minSteps(4)
	    , tolerance(1e-12)
	    , stepsForEnergyConvergence(MaxLanczosSteps)
	    , eigsForStop(1)
	    , options("")
	    , oneOverA(0)
	    , b(0)
	    , Eg(0)
	    , weight(0)
	    , isign(0)
	    , lotaMemory(false)
	{
	}

	template 
	ParametersForSolver(IoInputType& io, String prefix, int ind = -1)
	    : steps(LanczosSteps)
	    , minSteps(4)
	    , tolerance(1e-12)
	    , stepsForEnergyConvergence(MaxLanczosSteps)
	    , eigsForStop(1)
	    , options("none")
	    , oneOverA(0)
	    , b(0)
	    , Eg(0)
	    , weight(0)
	    , isign(0)
	    , lotaMemory(true)
	{

		rabbitHole(steps, prefix, ind, "Steps", io);

		rabbitHole(minSteps, prefix, ind, "MinSteps", io);

		rabbitHole(tolerance, prefix, ind, "Eps", io);

		rabbitHole(stepsForEnergyConvergence, prefix, ind, "StepsForEnergyConvergence", io);

		rabbitHole(eigsForStop, prefix, ind, "EigsForStop", io);

		rabbitHole(options, prefix, ind, "Options", io);

		rabbitHole(oneOverA, prefix, ind, "OneOverA", io);

		rabbitHole(b, prefix, ind, "B", io);

		rabbitHole(Eg, prefix, ind, "Energy", io);

		int x = 0;
		rabbitHole(x, prefix, ind, "NoSaveLanczosVectors", io);
		lotaMemory = (x > 0) ? 0 : 1;
	}

	template 
	static void rabbitHole(T& t, String prefix, int ind, String postfix, IoInputType& io)
	{
		if (ind >= 0) {
			bunnie(t, prefix, ind, postfix, io);
		} else {
			hare(t, prefix, postfix, io);
		}
	}

	template 
	static void hare(T& t, String prefix, String postfix, IoInputType& io)
	{
		// if prefix + postfix exists use it
		try {
			io.readline(t, prefix + postfix + "=");
			return;
		} catch (std::exception&) {
		}
	}

	template 
	static void bunnie(T& t, String prefix, SizeType ind, String postfix, IoInputType& io)
	{
		// if prefix + ind + postfix exists --> use it and return
		try {
			io.readline(t, prefix + ttos(ind) + postfix + "=");
			return;
		} catch (std::exception&) {
		}

		// if prefix + jnd + postfix exists with jnd < ind --> use the
		// largest jnd and return
		for (SizeType i = 0; i < ind; ++i) {
			const SizeType jnd = ind - i - 1;
			try {
				io.readline(t,
				    prefix + ttos(jnd) + postfix + "=");
				return;
			} catch (std::exception&) {
			}
		}

		hare(t, prefix, postfix, io);
	}

	SizeType steps;
	SizeType minSteps;
	RealType tolerance;
	SizeType stepsForEnergyConvergence;
	SizeType eigsForStop;
	String options;
	RealType oneOverA, b;
	RealType Eg;
	RealType weight;
	int isign;
	bool lotaMemory;
}; // class ParametersForSolver
} // namespace PsimagLite

/*@}*/
#endif // PARAMETERS_FOR_SOLVER_H
PsimagLite-3.06/src/Permutations.h000066400000000000000000000115331446452427400171510ustar00rootroot00000000000000/*
Copyright (c) 2009-2012, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup DMRG */
/*@{*/

/*! \file Permutations.h
 *
 * Raw computations for a free Hubbard model
 *
 */
#ifndef PERMUTATIONS_H_H
#define PERMUTATIONS_H_H

#include "Complex.h" // in PsimagLite
#include "Sort.h"

namespace PsimagLite
{

template 
class Permutations
{
	typedef typename ContainerType::value_type FieldType;

public:

	typedef FieldType value_type;

	Permutations(const ContainerType& orig)
	    : data_(orig.size())
	{
		for (SizeType i = 0; i < data_.size(); i++)
			data_[i] = orig[i];
		Sort::Type> mysort;
		typename Vector::Type iperm(data_.size());
		mysort.sort(data_, iperm);
	}

	/*1. Find the largest index k such that a[k] < a[k + 1].
	 * If no such index exists, the permutation is the last permutation.
	 *
	   2. Find the largest index l such that a[k] < a[l]. Since k + 1
	   is such an index, l is well defined and satisfies k < l.

	   3. Swap a[k] with a[l].

	   4. Reverse the sequence from a[k + 1] up to and including the
	   final element a[n-1].
	   */
	bool increase()
	{
		if (data_.size() == 0)
			return false;
		int k = largestk();
		if (k < 0)
			return false;

		int l = largestl(k);
		std::swap(data_[k], data_[l]);
		SizeType c = data_.size() - 1;
		if (SizeType(k) + 1 >= data_.size() - 1)
			return true;
		typename Vector::Type tmp = data_;
		for (SizeType i = k + 1; i < data_.size(); i++)
			data_[c--] = tmp[i];
		return true;
	}

	SizeType operator[](SizeType i) const
	{
		// if (i>=data_.size()) throw RuntimeError("Permutations
		// error\n");
		return data_[i];
	}

	SizeType size() const { return data_.size(); }

private:

	int largestk() const
	{
		int saved = -1;
		SizeType tot = data_.size() - 1;
		for (SizeType i = 0; i < tot; i++) {
			if (data_[i] < data_[i + 1])
				saved = i;
		}
		return saved;
	}

	SizeType largestl(SizeType k) const
	{
		SizeType saved = 0;
		for (SizeType i = 0; i < data_.size(); i++) {
			if (data_[k] < data_[i])
				saved = i;
		}
		return saved;
	}
	typename Vector::Type data_;

}; // Permutations

template 
std::ostream& operator<<(std::ostream& os, const Permutations& ig)
{
	for (SizeType i = 0; i < ig.size(); i++)
		os << ig[i] << " ";
	return os;
}
} // namespace PsimagLite

/*@}*/
#endif // PERMUTATIONS_H_H
PsimagLite-3.06/src/PlotParams.h000066400000000000000000000024131446452427400165360ustar00rootroot00000000000000
/*
// BEGIN LICENSE BLOCK
Copyright (c) 2009 , UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************

*/
/** \ingroup DMRG */
/*@{*/

/*! \file ContinuedFraction.h
 *
 * Parameters for an I(omega) plot
 * This is a structure, don't add members functions (except ctor)
 *
 */
#ifndef PLOT_PARAMS_H
#define PLOT_PARAMS_H

namespace PsimagLite
{
template 
struct PlotParams {

	PlotParams(RealType wbegin, RealType wend, RealType wstep, RealType wdelta, RealType beta1, SizeType numberOfMatsubaras1)
	    : omega1(wbegin)
	    , omega2(wend)
	    , deltaOmega(wstep)
	    , delta(wdelta)
	    , beta(beta1)
	    , numberOfMatsubaras(numberOfMatsubaras1)
	{
	}

	RealType omega1;
	RealType omega2;
	RealType deltaOmega;
	RealType delta;
	RealType beta;
	SizeType numberOfMatsubaras;
};
} // namespace PsimagLite
/*@}*/
#endif // PLOT_PARAMS_H
PsimagLite-3.06/src/PredicateAnd.h000066400000000000000000000043631446452427400170050ustar00rootroot00000000000000#ifndef PREDICATEAND_H
#define PREDICATEAND_H
#include "PredicateSimple.h"
#include "PsimagLite.h"
#include "Vector.h"

namespace PsimagLite
{

/* PSIDOC PredicateAnd
 PredicateAnd is a &-separated list of simple predicates,

 SimplePredicate0&SimplePredicate1&...

 where & means to AND the predicates.
 */
class PredicateAnd
{

public:

	typedef Vector::Type VectorPredicateSimpleType;
	typedef PredicateSimple::VectorStringType VectorStringType;

	PredicateAnd(String pred, PsimagLite::String sep = "&")
	    : pred_(pred)
	{
		VectorStringType tokens;
		split(tokens, pred, sep);
		const SizeType n = tokens.size();
		for (SizeType i = 0; i < n; ++i)
			vPredicateSimple_.push_back(PredicateSimple(tokens[i]));
	}

	template 
	bool isTrue(String name, T val)
	{
		VectorStringType names { name };
		typename Vector::Type values { val };
		SizeType n = vPredicateSimple_.size();
		for (SizeType i = 0; i < n; ++i)
			if (!vPredicateSimple_[i].isTrue(names, values))
				return false;
		return true;
	}

	template 
	bool isTrue(String name1, T val1, String name2, T val2)
	{
		VectorStringType names { name1, name2 };
		typename Vector::Type values { val1, val2 };
		SizeType n = vPredicateSimple_.size();
		for (SizeType i = 0; i < n; ++i)
			if (!vPredicateSimple_[i].isTrue(names, values))
				return false;
		return true;
	}

	template 
	bool isTrue(String name1, T val1, String name2, T val2, String name3, T val3)
	{
		VectorStringType names { name1, name2, name3 };
		typename Vector::Type values { val1, val2, val3 };
		SizeType n = vPredicateSimple_.size();
		for (SizeType i = 0; i < n; ++i)
			if (!vPredicateSimple_[i].isTrue(names, values))
				return false;
		return true;
	}

	template 
	bool isTrue(String name1, T val1, String name2, T val2, String name3, T val3, String name4, T val4)
	{
		VectorStringType names { name1, name2, name3, name4 };
		typename Vector::Type values { val1, val2, val3, val4 };
		SizeType n = vPredicateSimple_.size();
		for (SizeType i = 0; i < n; ++i)
			if (!vPredicateSimple_[i].isTrue(names, values))
				return false;
		return true;
	}

private:

	String pred_;
	VectorPredicateSimpleType vPredicateSimple_;
};
} // namespace PsimagLite
#endif // PREDICATEAND_H
PsimagLite-3.06/src/PredicateAwesome.h000066400000000000000000000071001446452427400176730ustar00rootroot00000000000000#ifndef PREDICATE_AWESOME_H
#define PREDICATE_AWESOME_H

#include "PredicateAnd.h"
#include "PredicateDefaultSpec.h"
#include "Vector.h"

namespace PsimagLite
{

/* PSIDOC PredicateAwesome
 Comma-separated list of items, don't leave spaces:
 item0,item1,item2,...

 Each item is either a setting or a predicate

 At least one item is a predicate

 If multiple predicates are present, they are ORed.

 Setting item is of the form
 S1   /\[a-zA-Z]+/
 S2  /\[a-zA-Z]+=\[a-zA-Z\d\.\-]/

 Predicate is a &-separated list of simple predicates,

 SimplePredicate0&SimplePredicate1&...

 where & means to AND the predicates.

 where SimplePredicate is of the form
 word operator word
 where operator is in {==, <, >, <=, >=, %%}
 with the expected meaning, and %% means divisible by.
 So l%%2 means that the simple predicate is true if l is divisible by 2.

 From this rules, the list of items
 M=2,l%%2&l!=0,l>=7,l<11
 will set M=2 and define a predicate that is true if l
 is in the set {2, 4, 6, 7, 8, 9, 10, 12, 14, 16, 18 ...}
 and false otherwise.

 API via SpecType

 S1 calls SpecType::set(String word)
 S2 calls SpecType::set(String word1, String word2)

 The predicate call is

 template
 bool isPredicateTrue(String name, T val)

 template
 bool isPredicateTrue(String name1, T1 val2, String name2, T2 val2)

 etc. Can we do this with varargs templates?? FIXME TODO
 */

template 
class PredicateAwesome
{

public:

	typedef Vector::Type VectorPredicateAndType;
	typedef PredicateAnd::VectorStringType VectorStringType;

	PredicateAwesome(String pred, String orSeparator = ",", String andSeparator = "&", SpecType* spec = nullptr)
	    : pred_(pred)
	{
		if (pred_ == "")
			return;
		VectorStringType tokens;
		split(tokens, pred, orSeparator);
		const SizeType n = tokens.size();
		for (SizeType i = 0; i < n; ++i) {
			if (tokens[i].length() > 0 && tokens[i][0] == '@') {
				if (!spec)
					throw RuntimeError(
					    String("PredicateAwesome:: with "
						   "default spec")
					    + " cannot handle special options\n");
				spec->operator()(tokens[i]);
				continue;
			}

			predicateAnd_.push_back(
			    PredicateAnd(tokens[i], andSeparator));
		}
	}

	template 
	bool isTrue(String name, T val)
	{
		if (pred_ == "")
			return false;
		SizeType n = predicateAnd_.size();
		for (SizeType i = 0; i < n; ++i)
			if (predicateAnd_[i].isTrue(name, val))
				return true;
		return false;
	}

	template 
	bool isTrue(String name1, T1 val1, String name2, T2 val2)
	{
		if (pred_ == "")
			return false;
		SizeType n = predicateAnd_.size();
		for (SizeType i = 0; i < n; ++i)
			if (predicateAnd_[i].isTrue(name1, val1, name2, val2))
				return true;
		return false;
	}

	template 
	bool isTrue(String name1, T1 val1, String name2, T2 val2, String name3, T1 val3)
	{
		if (pred_ == "")
			return false;
		SizeType n = predicateAnd_.size();
		for (SizeType i = 0; i < n; ++i)
			if (predicateAnd_[i].isTrue(name1, val1, name2, val2, name3, val3))
				return true;
		return false;
	}

	template 
	bool isTrue(String name1, T1 val1, String name2, T2 val2, String name3, T1 val3, String name4, T2 val4)
	{
		if (pred_ == "")
			return false;
		SizeType n = predicateAnd_.size();
		for (SizeType i = 0; i < n; ++i)
			if (predicateAnd_[i].isTrue(name1, val1, name2, val2, name3, val3, name4, val4))
				return true;
		return false;
	}

private:

	String pred_;
	VectorPredicateAndType predicateAnd_;
};
} // namespace PsimagLite
#endif // PREDICATE_AWESOME_H
PsimagLite-3.06/src/PredicateDefaultSpec.h000066400000000000000000000003531446452427400204750ustar00rootroot00000000000000#ifndef PREDICATEDEFAULTSPEC_H
#define PREDICATEDEFAULTSPEC_H

namespace PsimagLite
{

class PredicateDefaultSpec
{

public:

	void operator()(PsimagLite::String) const { }
};
} // namespace PsimagLite
#endif // PREDICATEDEFAULTSPEC_H
PsimagLite-3.06/src/PredicateSimple.cpp000066400000000000000000000002451446452427400200620ustar00rootroot00000000000000#include "PredicateSimple.h"

namespace PsimagLite
{
PredicateSimple::VectorStringType PredicateSimple::ops_ = {
	"==",
	"!=",
	"<=",
	">=",
	">",
	"<",
	"%%"
};

}
PsimagLite-3.06/src/PredicateSimple.h000066400000000000000000000101221446452427400175220ustar00rootroot00000000000000#ifndef PREDICATE_SIMPLE_H
#define PREDICATE_SIMPLE_H
#include "AST/ExpressionForAST.h"
#include "AST/PlusMinusMultiplyDivide.h"
#include "PsimagLite.h"
#include "Vector.h"

/* PSIDOC PredicateSimple
 PredicateSimple is of the form
 word operator word
 where operator is in {==, <, >, <=, >=, %%}
 with the usual meaning, and %% means divisible by.
 So l%%2 means that the simple predicate is true if l is divisible by 2.
 */
namespace PsimagLite
{

class PredicateSimple
{

public:

	typedef Vector::Type VectorStringType;

	PredicateSimple(String pred, String separator = ":")
	    : pred_(pred)
	    , separator_(separator)
	{
		SizeType length = 0;
		size_t location = String::npos;

		SizeType n = pred.length();
		if (n < 3)
			err("PredicateSimple: pred must have at least 3 "
			    "characters\n");

		for (SizeType i = 0; i < n - 1; ++i) {

			// order matters: test with LONGER FIRST
			String maybeOp = pred.substr(i, 2);
			if (operatorLength(maybeOp) == 2) {
				location = i;
				length = 2;
				break;
			}

			maybeOp = pred.substr(i, 1);
			if (operatorLength(maybeOp) == 1) {
				location = i;
				length = 1;
				break;
			}
		}

		if (length == 0)
			err("Could not find operator in predicate " + pred + "\n");

		lhs_ = pred.substr(0, location);
		op_ = pred.substr(location, length);
		rhs_ = pred.substr(location + length, n - location - length);
		if (lhs_ == "" || rhs_ == "")
			err("Left or right expression is empty\n");
	}

	template 
	bool isTrue(const VectorStringType& names, const SomeVectorType& vals)
	{
		typedef typename SomeVectorType::value_type SomeValueType;
		SomeValueType lv = getValue(lhs_, names, vals);
		SomeValueType rv = getValue(rhs_, names, vals);
		return compareOnOp(lv, op_, rv);
	}

private:

	template 
	static bool compareOnOp(T lv, String op, T rv)
	{
		// {==, <, >, <=, >=, %%}
		// If you add something here, add it also to PredicateSimple.cpp
		if (op == "==")
			return (lv == rv);
		if (op == "!=")
			return (lv != rv);
		if (op == "<")
			return (lv < rv);
		if (op == ">")
			return (lv > rv);
		if (op == "<=")
			return (lv <= rv);
		if (op == ">=")
			return (lv >= rv);
		if (op == "%%")
			return divisibleBy(lv, rv);
		throw RuntimeError("Unknown operator " + op + "\n");
	}

	template 
	static bool divisibleBy(
	    SizeType lv,
	    SizeType rv,
	    typename std::enable_if::isArith, int*>::type = 0)
	{
		return ((lv % rv) == 0);
	}

	static SizeType operatorLength(String op)
	{
		const SizeType n = ops_.size();
		for (SizeType i = 0; i < n; ++i)
			if (op == ops_[i])
				return op.length();

		return 0;
	}

	template 
	typename SomeVectorType::value_type
	getValue(String hs, const VectorStringType& names, const SomeVectorType& vals)
	{
		String numericHs = replaceVariables(hs, names, vals);
		VectorStringType tokens;
		split(tokens, numericHs, separator_);
		typedef PlusMinusMultiplyDivide<
		    typename SomeVectorType::value_type>
		    PrimitivesType;
		PrimitivesType primitives;
		ExpressionForAST expresionForAST(tokens,
		    primitives);
		return expresionForAST.exec();
	}

	template 
	static String replaceVariables(String hs, const VectorStringType& names, const SomeVectorType& vals)
	{
		const SizeType n = names.size();
		assert(n == vals.size());
		String buffer = hs;
		for (SizeType i = 0; i < n; ++i) {
			buffer = replaceVariable(buffer, names[i], vals[i]);
		}

		return buffer;
	}

	template 
	static String replaceVariable(String hs, String name, T val)
	{
		const String valString = ttos(val);
		const SizeType nameLength = name.length();

		while (true) {
			size_t index = hs.find(name);
			if (index == String::npos)
				return hs;
			String part1 = (index == 0) ? "" : hs.substr(0, index);
			String part2 = hs.substr(index + nameLength,
			    hs.length() - nameLength - index);
			hs = part1 + valString + part2;
		}

		return hs;
	}

	static VectorStringType ops_;
	String pred_;
	String separator_;
	String lhs_;
	String op_;
	String rhs_;
};
} // namespace PsimagLite
#endif // PREDICATE_SIMPLE_H
PsimagLite-3.06/src/Profiling.h000066400000000000000000000034721446452427400164130ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************

*/

// A class to profile a scope of code
#ifndef PROFILING_H_
#define PROFILING_H_

#include "MemoryUsage.h"
#include "ProgressIndicator.h"
#include "PsimagLite.h"
#include 

namespace PsimagLite
{

class Profiling
{

	double diff(double x1, double x2) const { return x1 - x2; }

public:

	Profiling(String caller, String additional, std::ostream& os)
	    : progressIndicator_(caller)
	    , memoryUsage_("/proc/self/stat")
	    , isDead_(false)
	    , os_(os)
	{
		OstringStream msg(std::cout.precision());
		msg() << "starting clock " << additional;
		progressIndicator_.printline(msg, os);
	}

	Profiling(String caller, std::ostream& os)
	    : progressIndicator_(caller)
	    , memoryUsage_("/proc/self/stat")
	    , isDead_(false)
	    , os_(os)
	{
		OstringStream msg(std::cout.precision());
		msg() << "starting clock";
		;
		progressIndicator_.printline(msg, os);
	}

	~Profiling() { killIt(""); }

	void end(String message) { killIt(message); }

private:

	void killIt(String message)
	{
		if (isDead_)
			return;
		OstringStream msg(std::cout.precision());
		msg() << "stopping clock " << message;
		progressIndicator_.printline(msg, os_);
		isDead_ = true;
	}

	ProgressIndicator progressIndicator_;
	MemoryUsage memoryUsage_;
	bool isDead_;
	std::ostream& os_;
}; // Profiling
} // namespace PsimagLite

#endif
PsimagLite-3.06/src/ProgressIndicator.cpp000066400000000000000000000056571446452427400204650ustar00rootroot00000000000000/*
Copyright (c) 2009-2016, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/

/*! \file ProgressIndicator.cpp
 *
 *  This class handles output to a progress indicator (usually the terminal)
 */

#include "ProgressIndicator.h"

namespace PsimagLite
{

MemoryUsage ProgressIndicator::musage_;
OstringStream ProgressIndicator::buffer_(std::cout.precision());
bool ProgressIndicator::bufferActive_ = false;

} // namespace PsimagLite
PsimagLite-3.06/src/ProgressIndicator.h000066400000000000000000000134711446452427400201230ustar00rootroot00000000000000/*
Copyright (c) 2009-2014, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file ProgressIndicator.h
 *
 *  This class handles output to a progress indicator (usually the terminal)
 */

#ifndef PROGRESS_INDICATOR_H
#define PROGRESS_INDICATOR_H

#include "Concurrency.h"
#include "MemoryUsage.h"
#include "TypeToString.h"
#include 
#include 
#include 
#include 
#include 

namespace PsimagLite
{

class ProgressIndicator
{

	static MemoryUsage musage_;
	static OstringStream buffer_;
	static bool bufferActive_;

public:

	ProgressIndicator(String caller, SizeType threadId = 0)
	    : threadId_(threadId)
	    , rank_(0)
	{
		if (threadId_ != 0)
			return;

		caller_ = caller;
		rank_ = Concurrency::rank();
	}

	static void updateBuffer(int signal)
	{
		if (bufferActive_) {
			pid_t p = getpid();
			String outName("buffer");
			outName += ttos(p);
			outName += ".txt";
			std::ofstream fout(outName.c_str());
			fout << buffer_().str() << "\n";
			fout.close();
			buffer_().str("");
		}

		bufferActive_ = !bufferActive_;

		String bufferActive = (bufferActive_) ? "active" : "inactive";
		std::cerr << "ProgressIndicator: signal " << signal
			  << " received.";
		std::cerr << " buffer is now " << bufferActive << "\n";
	}

	template 
	void printline(const String& s, SomeOutputType& os) const
	{
		if (threadId_ != 0)
			return;
		if (rank_ != 0)
			return;
		prefix(os);
		os << s << "\n";

		if (!bufferActive_)
			return;

		prefix(buffer_);
		buffer_() << s << "\n";
	}

	void printline(OstringStream& s, std::ostream& os) const
	{
		if (threadId_ != 0)
			return;
		if (rank_ != 0)
			return;
		prefix(os);
		os << s().str() << "\n";
		s().seekp(std::ios_base::beg);

		if (!bufferActive_)
			return;

		prefix(buffer_);
		buffer_() << s().str() << "\n";
		s().seekp(std::ios_base::beg);
	}

	void print(const String& something, std::ostream& os) const
	{
		if (threadId_ != 0)
			return;
		if (rank_ != 0)
			return;
		prefix(os);
		os << something;

		if (!bufferActive_)
			return;

		prefix(buffer_);
		buffer_() << something;
	}

	void printMemoryUsage()
	{
		musage_.update();
		String vmPeak = musage_.findEntry("VmPeak:");
		String vmSize = musage_.findEntry("VmSize:");
		OstringStream msg(std::cout.precision());
		msg() << "Current virtual memory is " << vmSize
		      << " maximum was " << vmPeak;
		printline(msg, std::cout);

		if (!bufferActive_)
			return;

		buffer_() << "Current virtual memory is " << vmSize
			  << " maximum was " << vmPeak;
		printline(buffer_, std::cout);
	}

	static MemoryUsage::TimeHandle time() { return musage_.time(); }

private:

	template 
	void prefix(SomeOutputStreamType& os) const
	{
		const MemoryUsage::TimeHandle t = musage_.time();
		const double seconds = t.millis();
		const SizeType prec = os.precision(3);
		prefixHelper(os) << caller_ << " "
				 << "[" << std::fixed << seconds << "]: ";
		os.precision(prec);
	}

	OstringStream::OstringStreamType& prefixHelper(OstringStream& os) const
	{
		return os();
	}

	template 
	SomeOutputStreamType& prefixHelper(SomeOutputStreamType& os) const
	{
		return os;
	}

	String caller_;
	SizeType threadId_;
	SizeType rank_;
}; // ProgressIndicator

} // namespace PsimagLite

/*@}*/
#endif
PsimagLite-3.06/src/PsiBase64.cpp000066400000000000000000000027771446452427400165240ustar00rootroot00000000000000/*
 *****
 ***** ATTENTION: This code has been modified from the original
 *****            and adapted for use in PsimagLite
 ***** Original notice is below

 ------------------------- begin original notice -------------------------------

Copyright (C) 2004-2008 René Nyffenegger

This source code is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this source code must not be misrepresented; you must not
   claim that you wrote the original source code. If you use this source code
   in a product, an acknowledgment in the product documentation would be
   appreciated but is not required.

2. Altered source versions must be plainly marked as such, and must not be
   misrepresented as being the original source code.

3. This notice may not be removed or altered from any source distribution.

René Nyffenegger rene.nyffenegger@adp-gmbh.ch

------------------------- end original notice -------------------------------

***** Original notice is above
***** ATTENTION: This code has been modified from the original *****
*/

#include "PsiBase64.h"

namespace PsimagLite
{

const String PsiBase64::base64Chars_ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
				       "abcdefghijklmnopqrstuvwxyz"
				       "0123456789+/";
}
PsimagLite-3.06/src/PsiBase64.h000066400000000000000000000113021446452427400161510ustar00rootroot00000000000000/*
 *****
 ***** ATTENTION: This code has been modified from the original *****
 *****            and adapted for use in PsimagLite
 *****
------------------------- begin original notice -------------------------------

Copyright (C) 2004-2008 René Nyffenegger

This source code is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this source code must not be misrepresented; you must not
   claim that you wrote the original source code. If you use this source code
   in a product, an acknowledgment in the product documentation would be
   appreciated but is not required.

2. Altered source versions must be plainly marked as such, and must not be
   misrepresented as being the original source code.

3. This notice may not be removed or altered from any source distribution.

René Nyffenegger rene.nyffenegger@adp-gmbh.ch

------------------------- end original notice -------------------------------

***** Original notice is above
***** ATTENTION: This code has been modified from the original *****
*/

#ifndef PSIBASE64_H
#define PSIBASE64_H

#include "Io/IoSerializerStub.h"
#include "Vector.h"

namespace PsimagLite
{

class PsiBase64
{

	static const String base64Chars_;

public:

	class Encode
	{

	public:

		Encode(const String& str)
		{
			encode_(reinterpret_cast(
				    str.c_str()),
			    str.length());
		}

		Encode(unsigned char const* bytesToEncode, unsigned int inLen)
		{
			encode_(bytesToEncode, inLen);
		}

		const String& operator()() const { return buffer_; }

		void write(String label,
		    PsimagLite::IoSerializer& ioSerializer) const
		{
			ioSerializer.write(label, buffer_);
		}

		friend std::ostream& operator<<(std::ostream& os,
		    const Encode& encode)
		{
			os << "#InputStartsHere\n";
			os << encode.buffer_;
			os << "\n#InputEndsHere\n";
			return os;
		}

	private:

		void encode_(unsigned char const* bytesToEncode,
		    unsigned int inLen)
		{
			buffer_ = "";
			int i = 0;
			int j = 0;
			unsigned char charArray3[3];
			unsigned char charArray4[4];

			while (inLen--) {
				charArray3[i++] = *(bytesToEncode++);
				if (i == 3) {
					charArray4[0] = (charArray3[0] & 0xfc) >> 2;
					charArray4[1] = ((charArray3[0] & 0x03) << 4) + ((charArray3[1] & 0xf0) >> 4);
					charArray4[2] = ((charArray3[1] & 0x0f) << 2) + ((charArray3[2] & 0xc0) >> 6);
					charArray4[3] = charArray3[2] & 0x3f;

					for (i = 0; (i < 4); i++)
						buffer_ += base64Chars_[charArray4[i]];
					i = 0;
				}
			}

			if (i) {
				for (j = i; j < 3; j++)
					charArray3[j] = '\0';

				charArray4[0] = (charArray3[0] & 0xfc) >> 2;
				charArray4[1] = ((charArray3[0] & 0x03) << 4) + ((charArray3[1] & 0xf0) >> 4);
				charArray4[2] = ((charArray3[1] & 0x0f) << 2) + ((charArray3[2] & 0xc0) >> 6);
				charArray4[3] = charArray3[2] & 0x3f;

				for (j = 0; (j < i + 1); j++)
					buffer_ += base64Chars_[charArray4[j]];

				while ((i++ < 3))
					buffer_ += '=';
			}
		}

		String buffer_;
	}; // class Encode

	class Decode
	{

	public:

		Decode(const String& encodedString)
		{
			buffer_ = "";
			int inLen = encodedString.size();
			int i = 0;
			int j = 0;
			int in_ = 0;
			unsigned char charArray4[4], charArray3[3];

			while (inLen-- && (encodedString[in_] != '=') && isBase64(encodedString[in_])) {
				charArray4[i++] = encodedString[in_];
				in_++;
				if (i == 4) {
					for (i = 0; i < 4; i++)
						charArray4[i] = base64Chars_.find(
						    charArray4[i]);

					charArray3[0] = (charArray4[0] << 2) + ((charArray4[1] & 0x30) >> 4);
					charArray3[1] = ((charArray4[1] & 0xf) << 4) + ((charArray4[2] & 0x3c) >> 2);
					charArray3[2] = ((charArray4[2] & 0x3) << 6) + charArray4[3];

					for (i = 0; (i < 3); i++)
						buffer_ += charArray3[i];
					i = 0;
				}
			}

			if (i) {
				for (j = i; j < 4; j++)
					charArray4[j] = 0;

				for (j = 0; j < 4; j++)
					charArray4[j] = base64Chars_.find(charArray4[j]);

				charArray3[0] = (charArray4[0] << 2) + ((charArray4[1] & 0x30) >> 4);
				charArray3[1] = ((charArray4[1] & 0xf) << 4) + ((charArray4[2] & 0x3c) >> 2);
				charArray3[2] = ((charArray4[2] & 0x3) << 6) + charArray4[3];

				for (j = 0; (j < i - 1); j++)
					buffer_ += charArray3[j];
			}
		}

		const String& operator()() const { return buffer_; }

	private:

		static bool isBase64(unsigned char c)
		{
			return (isalnum(c) || (c == '+') || (c == '/'));
		}

		String buffer_;
	}; // class Decode
}; // class PsiBase64
} // namespace PsimagLite

#endif // PSIBASE64_H
PsimagLite-3.06/src/PsimagLite.cpp000066400000000000000000000054051446452427400170510ustar00rootroot00000000000000#include "PsimagLite.h"

namespace PsimagLite
{

SizeType integerDivision(SizeType a, SizeType b)
{
	if ((a % b) != 0) {
		throw RuntimeError("integerDivision: failed\n");
	}

	return a / b;
}

std::ostream& operator<<(std::ostream& os,
    const std::pair& p)
{
	os << p.first << " " << p.second << " ";
	return os;
}

std::istream& operator>>(std::istream& is, std::pair& pair)
{
	is >> pair.first;
	is >> pair.second;
	return is;
}

void err(String s) { throw RuntimeError(s); }

SizeType log2Integer(SizeType x)
{
	SizeType count = 0;
	while (x > 0) {
		x >>= 1;
		++count;
	}

	return count;
}

void split(Vector::Type& tokens, String str, String delimiters)
{
	// Skip delimiters at beginning.
	String::size_type lastPos = str.find_first_not_of(delimiters, 0);
	// Find first "non-delimiter".
	String::size_type pos = str.find_first_of(delimiters, lastPos);

	while (String::npos != pos || String::npos != lastPos) {
		// Found a token, add it to the vector.
		tokens.push_back(str.substr(lastPos, pos - lastPos));
		// Skip delimiters.  Note the "not_of"
		lastPos = str.find_first_not_of(delimiters, pos);
		// Find next "non-delimiter"
		pos = str.find_first_of(delimiters, lastPos);
	}
}

String basename(const String& path)
{
	return String(
	    std::find_if(path.rbegin(), path.rend(), MatchPathSeparator())
		.base(),
	    path.end());
}

int atoi(String str)
{
	const SizeType n = str.length();
	for (SizeType i = 0; i < n; ++i) {
		if (isdigit(str[i]))
			continue;
		if (str[i] == '-' || str[i] == '+')
			continue;
		throw RuntimeError("atoi received a non-digit: " + str + "\n");
	}

	return std::atoi(str.c_str());
}

bool isAnInteger(String str)
{
	const SizeType n = str.length();
	for (SizeType i = 0; i < n; ++i) {
		if (isdigit(str[i]))
			continue;
		return false;
	}

	return (n > 0);
}

bool isAfloat(String str)
{
	const SizeType n = str.length();
	bool hasDigit = false;
	for (SizeType i = 0; i < n; ++i) {
		if (isdigit(str[i])) {
			hasDigit = true;
			continue;
		}

		if (str[i] == '-' || str[i] == '+' || str[i] == 'e' || str[i] == 'E' || str[i] == '.')
			continue;
		return false;
	}

	return hasDigit;
}

double atof(String str)
{

	if (!isAfloat(str))
		throw RuntimeError("atof received a non-digit " + str + "\n");

	return std::atof(str.c_str());
}

void replaceAll(String& str, const String& from, const String& to)
{
	if (from.empty())
		return;

	size_t start_pos = 0;

	while ((start_pos = str.find(from, start_pos)) != String::npos) {
		str.replace(start_pos, from.length(), to);
		start_pos += to.length(); // In case 'to' contains 'from', like
					  // replacing 'x' with 'yx'
	}
}

const int PsiApp::libSizeOfSizeType_ = sizeof(SizeType);

} // namespace PsimagLite

void err(PsimagLite::String s) { PsimagLite::err(s); }
PsimagLite-3.06/src/PsimagLite.h000066400000000000000000000065351446452427400165230ustar00rootroot00000000000000#ifndef PSI_PSIMAGLITE_H
#define PSI_PSIMAGLITE_H

#include "AnsiColors.h"
#include "Concurrency.h"
#include "MicroArchitecture.h"
#include "PsiBase64.h"
#include "Random48.h"
#include "TypeToString.h"
#include "Vector.h"
#include 
#include 
#include 
#include 

namespace PsimagLite
{

SizeType integerDivision(SizeType a, SizeType b);

std::ostream& operator<<(std::ostream&, const std::pair&);

std::istream& operator>>(std::istream&, std::pair&);

SizeType log2Integer(SizeType x);

bool isAfloat(String str);

bool isAnInteger(String str);

int atoi(String);

double atof(String);

void err(String);

struct MatchPathSeparator {
	bool operator()(char ch) const { return (ch == '/'); }
};

template 
void fillRandom(T& v, typename EnableIf::True, int>::Type = 0)
{
	SizeType n = v.size();
	if (n == 0)
		throw std::runtime_error(
		    "fillRandom must be called with size > 0\n");

	Random48 myrng(time(0));
	typename PsimagLite::Real::Type sum = 0;
	const typename T::value_type zeroPointFive = 0.5;
	for (SizeType i = 0; i < n; ++i) {
		v[i] = myrng() - zeroPointFive;
		sum += PsimagLite::real(v[i] * PsimagLite::conj(v[i]));
	}

	sum = 1.0 / sqrt(sum);
	for (SizeType i = 0; i < n; ++i)
		v[i] *= sum;
}

void split(Vector::Type& tokens, String str, String delimiters = " ");

void replaceAll(String& str, const String& from, const String& to);

String basename(const String&);

class PsiApp
{

public:

	PsiApp(String appName, int* argc, char*** argv, int nthreads)
	    : concurrency_(argc, argv, nthreads)
	    , appName_(basename(appName))
	    , microArch_(MicroArchitecture().vendorId())
	{
		chekSizeType();

		SizeType n = *argc;
		char** temp = *argv;
		for (SizeType i = 0; i < n; ++i)
			cmdLine_ += String(temp[i]) + " ";
	}

	void checkMicroArch(std::ostream& os,
	    PsimagLite::String compiledArch) const
	{
		os << "Compiled MicroArchitecture is " << compiledArch << "\n";
		os << "Running on MicroArchitecture " << microArch_ << "\n";
		if (compiledArch == microArch_)
			return;
		os << "WARNING: Compiled MicroArchitecture is DIFFERENT than "
		      "Running one\n";
	}

	const String& name() const { return appName_; }

	void printCmdLine(std::ostream& os) const
	{
		os << "PsiApp: CmdLine: " << cmdLine_ << "\n";
	}

	static void base64encode(std::ostream& os, String data, bool flag)
	{
		if (flag)
			os << "PsiApp::echoBase64: Echo of [[data]] in "
			      "base64\n";
		PsiBase64::Encode base64(data);
		os << base64() << "\n";
	}

	static void echoBase64(std::ostream& os, String filename)
	{
		os << "PsiApp::echoBase64: Echo of " << filename
		   << " in base64\n";
		base64encode(os, slurp(filename), false);
	}

	static String slurp(String filename)
	{
		std::ifstream fin(filename.c_str());
		std::stringstream sstr;
		sstr << fin.rdbuf();
		return sstr.str();
	}

private:

	void chekSizeType()
	{
		if (sizeof(SizeType) == libSizeOfSizeType_)
			return;
		std::string msg("PsimagLite compiled with -DUSE_SHORT but");
		msg += "application without. Or viceversa.\n";
		throw std::runtime_error(msg);
	}

	static const int libSizeOfSizeType_;

	Concurrency concurrency_;
	String appName_;
	String cmdLine_;
	String microArch_;
};

} // namespace PsimagLite

void err(PsimagLite::String);

#endif // PSI_PSIMAGLITE_H
PsimagLite-3.06/src/Pthreads.h000066400000000000000000000146511446452427400162350ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
// END LICENSE BLOCK
/** \ingroup PsimagLite */
/*@{*/

/*! \file Pthreads .h
 *
 *  A C++ pthreads class that implements the Concurrency interface
 *
 */
#ifndef PTHREADS_HEADER_H
#define PTHREADS_HEADER_H

#include "AllocatorCpu.h"
#include 
#include 
#include 
#include 
#ifdef PTHREAD_ASSIGN_AFFINITIES
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#endif
#ifdef _GNU_SOURCE
#include 
#include 
#endif

template 
struct PthreadFunctionStruct {
	PthreadFunctionStruct()
	    : pfh(0)
	    , threadNum(0)
	    , blockSize(0)
	    , total(0)
	    , mutex(0)
	    , cpu(0)
	{
	}

	PthreadFunctionHolderType* pfh;
	int threadNum;
	SizeType blockSize;
	SizeType total;
	pthread_mutex_t* mutex;
	SizeType cpu;
};

template 
void* thread_function_wrapper(void* dummyPtr)
{
	PthreadFunctionStruct* pfs = (PthreadFunctionStruct*)dummyPtr;

	PthreadFunctionHolderType* pfh = pfs->pfh;

	int s = 0;
#ifdef __linux___
	s = sched_getcpu();
#endif
	if (s >= 0)
		pfs->cpu = s;

	pfh->thread_function_(pfs->threadNum, pfs->blockSize, pfs->total, pfs->mutex);

	int retval = 0;
	pthread_exit(static_cast(&retval));
	return 0;
}

namespace PsimagLite
{
template 
class Pthreads
{

public:

	Pthreads(SizeType npthreads, int = 0)
	    : nthreads_(npthreads)
	    , cores_(1)
	{
		std::cerr << "Pthreads is deprecated, please use PthreadsNg\n";
		int cores = sysconf(_SC_NPROCESSORS_ONLN);
		cores_ = (cores > 0) ? cores : 1;
	}

	void loopCreate(SizeType total, PthreadFunctionHolderType& pfh)
	{
		PthreadFunctionStruct* pfs;
		pfs = new PthreadFunctionStruct<
		    PthreadFunctionHolderType>[nthreads_];
		pthread_mutex_init(&(mutex_), NULL);
		pthread_t* thread_id = new pthread_t[nthreads_];
		pthread_attr_t** attr = new pthread_attr_t*[nthreads_];

		for (SizeType j = 0; j < nthreads_; j++) {
			pfs[j].threadNum = j;
			pfs[j].pfh = &pfh;
			pfs[j].total = total;
			pfs[j].blockSize = total / nthreads_;
			if (total % nthreads_ != 0)
				pfs[j].blockSize++;
			pfs[j].mutex = &mutex_;

			attr[j] = new pthread_attr_t;
			int ret = pthread_attr_init(attr[j]);
			checkForError(ret);

			setAffinity(attr[j], j, cores_);

			ret = pthread_create(
			    &thread_id[j], attr[j], thread_function_wrapper, &pfs[j]);
			checkForError(ret);
		}

		for (SizeType j = 0; j < nthreads_; ++j)
			pthread_join(thread_id[j], 0);
		for (SizeType j = 0; j < nthreads_; ++j) {
			int ret = pthread_attr_destroy(attr[j]);
			checkForError(ret);
			delete attr[j];
			attr[j] = 0;
		}

		delete[] attr;

#ifndef NDEBUG
#ifdef __linux__
		for (SizeType j = 0; j < nthreads_; j++) {
			std::cout << "Pthreads: Pthread number " << j
				  << " runs on core number ";
			std::cout << pfs[j].cpu << "\n";
		}
#endif
#endif

		pthread_mutex_destroy(&mutex_);
		delete[] thread_id;
		delete[] pfs;
	}

	String name() const { return "pthreads"; }

	SizeType threads() const { return nthreads_; }

	SizeType mpiProcs() const { return 1; }

private:

	void setAffinity(pthread_attr_t* attr, SizeType threadNum, SizeType cores) const
	{
#ifdef PTHREAD_ASSIGN_AFFINITIES
#ifndef __APPLE__
		cpu_set_t* cpuset = new cpu_set_t;
		int cpu = threadNum % cores;
		CPU_ZERO(cpuset);
		CPU_SET(cpu, cpuset);
		std::size_t cpusetsize = sizeof(cpu_set_t);
		int ret = pthread_attr_setaffinity_np(attr, cpusetsize, cpuset);
		checkForError(ret);
		// clean up
		delete cpuset;
		cpuset = 0;
#endif
#endif
	}

	void checkForError(int ret) const
	{
		if (ret == 0)
			return;
#ifdef _GNU_SOURCE
		std::cerr << "Pthreads ERROR: " << strerror(ret) << "\n";
#endif
	}

	SizeType nthreads_;
	SizeType cores_;
	pthread_mutex_t mutex_;
}; // Pthreads class

} // namespace PsimagLite

/*@}*/
#endif
PsimagLite-3.06/src/PthreadsAndMpi.h000066400000000000000000000070321446452427400173210ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
// END LICENSE BLOCK
/** \ingroup PsimagLite */
/*@{*/

/*! \file PthreadsAndMpi .h
 *
 *  A C++ pthreads and MPI class that implements the Concurrency interface
 *
 */
#ifndef PTHREADS_AND_MPI_H
#define PTHREADS_AND_MPI_H

#include "Mpi.h"
#include "Pthreads.h"
#include 
#include 

namespace PsimagLite
{
template 
class PthreadsAndMpi : public Pthreads
{

	typedef Pthreads BaseType;

public:

	PthreadsAndMpi(SizeType npthreads, MPI::CommType comm = MPI::COMM_WORLD)
	    : BaseType(npthreads)
	    , nthreads_(npthreads)
	    , comm_(comm)
	{
	}

	String name() const { return "pthreadsandmpi"; }

	SizeType threads() const { return nthreads_; }

	SizeType mpiProcs() const { return MPI::commSize(comm_); }

private:

	SizeType nthreads_;
	MPI::CommType comm_;
	pthread_mutex_t mutex_;

}; // PthreadsAndMpi class

} // namespace PsimagLite

/*@}*/
#endif
PsimagLite-3.06/src/PthreadsNg.h000066400000000000000000000232201446452427400165120ustar00rootroot00000000000000/*
Copyright (c) 2009-2017, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

---------------------------------------------------------------
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

---------------------------------------------------------------

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file PthreadsNg .h
 *
 *  A C++ PthreadsNg class that implements the Concurrency interface
 *
 */
#ifndef PSI_PTHREADS_NG_H
#define PSI_PTHREADS_NG_H

#include "CodeSectionParams.h"
#include "LoadBalancerDefault.h"
#include "TypeToString.h"
#include "Vector.h"
#include 
#include 
#include 
#include 
#include 

#ifdef __linux__
#include 
#include 
#endif

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#ifdef _GNU_SOURCE
#include 
#include 
#endif
#ifndef PTHREAD_STACK_MIN
#define PTHREAD_STACK_MIN 16384
#endif

namespace PsimagLite
{

template 
struct PthreadFunctionStruct {
	PthreadFunctionStruct()
	    : pfh(0)
	    , loadBalancer(0)
	    , threadNum(0)
	    , nthreads(0)
	    , total(0)
	    , cpu(0)
	{
	}

	PthreadFunctionHolderType* pfh;
	const LoadBalancerType* loadBalancer;
	int threadNum;
	SizeType nthreads;
	SizeType total;
	SizeType cpu;
};

template 
void* thread_function_wrapper(void* dummyPtr)
{
	PthreadFunctionStruct* pfs = static_cast*>(
	    dummyPtr);

	PthreadFunctionHolderType* pfh = pfs->pfh;

	int s = 0;
#ifdef __linux__
	s = sched_getcpu();
#endif
	if (s >= 0)
		pfs->cpu = s;

	SizeType blockSize = pfs->loadBalancer->blockSize(pfs->threadNum);

	for (SizeType p = 0; p < blockSize; ++p) {
		SizeType taskNumber = pfs->loadBalancer->taskNumber(pfs->threadNum, p);
		if (taskNumber >= pfs->total)
			break;
		pfh->doTask(taskNumber, pfs->threadNum);
	}

	int retval = 0;
	pthread_exit(static_cast(&retval));
	return 0;
}

template 
class PthreadsNg
{

	static const int MAX_CPUS = 1024;

public:

	typedef LoadBalancerDefault::VectorSizeType VectorSizeType;

	PthreadsNg(const CodeSectionParams& codeSectionParams)
	    : nthreads_(codeSectionParams.npthreads)
	    , setAffinities_(codeSectionParams.setAffinities)
	    , stackSize_(codeSectionParams.stackSize)
	{
	}

	bool affinities() const { return setAffinities_; }

	size_t stackSize() const { return stackSize_; }

	void setAffinities(bool flag) { setAffinities_ = flag; }

	// no weights, no balancer ==> create weights, set all weigths to 1,
	// delegate
	void loopCreate(PthreadFunctionHolderType& pfh)
	{
		LoadBalancerType* loadBalancer = new LoadBalancerType(pfh.tasks(), nthreads_);
		loopCreate(pfh, *loadBalancer);
		delete loadBalancer;
		loadBalancer = 0;
	}

	// weights, no balancer ==> create balancer with weights ==> delegate
	void loopCreate(PthreadFunctionHolderType& pfh,
	    const VectorSizeType& weights)
	{
		LoadBalancerType* loadBalancer = new LoadBalancerType(weights, nthreads_);
		loopCreate(pfh, *loadBalancer);
		delete loadBalancer;
		loadBalancer = 0;
	}

	// balancer (includes weights)
	void loopCreate(PthreadFunctionHolderType& pfh,
	    const LoadBalancerType& loadBalancer)
	{
		SizeType ntasks = pfh.tasks();
		SizeType actualThreads = std::min(nthreads_, ntasks);
		PthreadFunctionStruct* pfs;
		pfs = new PthreadFunctionStruct[actualThreads];
		pthread_t* thread_id = new pthread_t[actualThreads];
		pthread_attr_t** attr = new pthread_attr_t*[actualThreads];

#ifndef __APPLE__
		cpu_set_t cpuset;

		if (setAffinities_) {
			static bool firstCall = true;
			pid_t pid = getpid(); // always successfull
			getPidAffinity(&cpuset, pid);
			int ret = sched_setaffinity(pid, sizeof(cpu_set_t), &cpuset);
			checkForError(ret);
			if (ret == 0 && firstCall) {
				printAffinity(pid, &cpuset);
				firstCall = false;
			}
		}
#endif

		for (SizeType j = 0; j < actualThreads; j++) {
			pfs[j].pfh = &pfh;
			pfs[j].loadBalancer = &loadBalancer;
			pfs[j].threadNum = j;
			pfs[j].total = ntasks;
			pfs[j].nthreads = actualThreads;

			attr[j] = new pthread_attr_t;
			int ret = (stackSize_ > 0)
			    ? pthread_attr_setstacksize(attr[j], stackSize_)
			    : 0;
			if (ret != 0) {
				std::cerr << __FILE__;
				std::cerr << "\tpthread_attr_setstacksize() "
					     "has returned non-zero "
					  << ret << "\n";
				std::cerr
				    << "\tIt is possible (but no certain) that "
				       "the following error";
				std::cerr << "\thappened.\n";
				std::cerr
				    << "\tEINVAL The stack size is less than ";
				std::cerr
				    << "PTHREAD_STACK_MIN (16384) bytes.\n";
				std::cerr << "\tI will ignore this error and "
					     "let you continue\n";
			}

			ret = pthread_attr_init(attr[j]);
			checkForError(ret);

#ifndef __APPLE__
			if (setAffinities_)
				setAffinity(attr[j], &cpuset, j);
#endif

			ret = pthread_create(
			    &thread_id[j], attr[j], thread_function_wrapper, &pfs[j]);
			checkForError(ret);
		}

		for (SizeType j = 0; j < actualThreads; ++j)
			pthread_join(thread_id[j], 0);
		for (SizeType j = 0; j < actualThreads; ++j) {
			int ret = pthread_attr_destroy(attr[j]);
			checkForError(ret);
			delete attr[j];
			attr[j] = 0;
		}

		delete[] attr;
		delete[] thread_id;
		delete[] pfs;
	}

	String name() const { return "PthreadsNg"; }

	// SizeType threads() const { return nthreads_; }

	SizeType mpiProcs() const { return 1; }

private:

#ifndef __APPLE__
	void getPidAffinity(cpu_set_t* cpuset, pid_t pid) const
	{

		CPU_ZERO(cpuset);
		int ret = sched_getaffinity(pid, sizeof(cpu_set_t), cpuset);
		checkForError(ret);
		if (ret != 0) {
			CPU_ZERO(cpuset);
			return;
		}
	}

	void setAffinity(pthread_attr_t* attr, cpu_set_t* cpuset, SizeType threadNum) const
	{
		// pick a cpu from cpuset
		int chosenCpu = getOneCpuFromSet(cpuset);
		if (chosenCpu < 0) {
			std::cerr
			    << "setAffinity: no cpus left in set for thread "
			    << threadNum << "\n";
			return;
		}

		cpu_set_t mynewset;
		CPU_ZERO(&mynewset);
		CPU_SET(chosenCpu, &mynewset); // add cpu to new set
		int ret = pthread_attr_setaffinity_np(attr, sizeof(cpu_set_t), &mynewset);
		checkForError(ret);
		if (ret != 0)
			return;

		// remove cpu from set
		CPU_CLR(chosenCpu, cpuset);
	}

	int getOneCpuFromSet(cpu_set_t* cpuset) const
	{
		int count = CPU_COUNT(cpuset);
		if (count == 0)
			return -1;

		int chosenCpu = -1;
		for (int i = 0; i < MAX_CPUS; ++i) {
			if (CPU_ISSET(i, cpuset) == 0)
				continue;
			chosenCpu = i;
			break;
		}

		return chosenCpu;
	}

	void printAffinity(pid_t pid, cpu_set_t* cpuset) const
	{
		std::cout << "pid " << pid << " sched_setaffinity with count ";
		std::cout << CPU_COUNT(cpuset) << ": ";
		for (int i = 0; i < MAX_CPUS; ++i) {
			if (CPU_ISSET(i, cpuset) == 0)
				continue;
			std::cout << i << " ";
		}

		std::cout << "\n";
	}
#endif

	void checkForError(int ret) const
	{
		if (ret == 0)
			return;
		std::cerr << "PthreadsNg ERROR: " << strerror(ret) << "\n";
	}

	SizeType nthreads_;
	bool setAffinities_;
	size_t stackSize_;
}; // PthreadsNg class

} // namespace PsimagLite

/*@}*/
#endif
PsimagLite-3.06/src/QuasiCanonical.h000066400000000000000000000074301446452427400173520ustar00rootroot00000000000000#ifndef QUASICANONICAL_H
#define QUASICANONICAL_H
#include "AST/ExpressionForAST.h"
#include "AST/PlusMinusMultiplyDivide.h"
#include "CmplxOrReal.h"
#include "PsimagLite.h"
#include "Vector.h"

namespace PsimagLite
{

// level one parens only
// TODO FIXME : Generalize to multiple levels
template 
class QuasiCanonical
{

public:

	typedef Vector::Type VectorStringType;
	typedef Vector::Type VectorBoolType;
	typedef typename Vector::Type VectorType;
	typedef typename Real::Type RealType;
	typedef std::complex ComplexType;

	QuasiCanonical(String str)
	    : str_(str)
	{
		const SizeType len = str_.length();
		String tempBuffer;
		String status = "closed";
		char prev = '\0';
		for (SizeType i = 0; i < len; ++i) {

			if (str_[i] == '-' && i > 0) {
				if (prev != '(' && prev != '+') {
					throw RuntimeError(
					    "The - sign must be preceded by "
					    "nothing, parens, or +\n");
				}
			}

			prev = str_[i];

			if (str_[i] == '(') {
				if (status == "open")
					throw RuntimeError(
					    "Too many parens levels (one only "
					    "supported for now)\n");
				status = "open";
				continue;
			}

			if (str_[i] == ')') {
				if (status == "closed")
					throw RuntimeError(
					    "Unbalanced parens, closed\n");
				status = "closed";
				mainBuffer_ += "@" + ttos(ats_.size()) + "@";
				ats_.push_back(tempBuffer);
				tempBuffer = "";
				continue;
			}

			if (status == "closed") {
				mainBuffer_ += str_[i];
			} else {
				tempBuffer += str_[i];
			}
		}

		if (status == "open")
			throw RuntimeError("Unbalanced parens, open\n");

		split(terms_, mainBuffer_, "+");

		const SizeType nscalars = ats_.size();
		cachedValues_.resize(nscalars);
		for (SizeType i = 0; i < nscalars; ++i) {
			cachedValues_[i] = simpleArithmetics(ats_[i]);
		}
	}

	SizeType numberOfTerms() const { return terms_.size(); }

	const String& term(SizeType i) const
	{
		assert(i < terms_.size());
		return terms_[i];
	}

	int scalarIndex(String str) const
	{
		const SizeType len = str.length();
		if (len < 3)
			return -1;
		if (str[0] != '@' || str[len - 1] != '@')
			return -1;

		String snumber = str.substr(1, len - 2);
		SizeType number = atoi(snumber);
		if (number >= ats_.size())
			return -1;
		return number;
	}

	ComplexOrRealType scalarFromIndex(SizeType ind) const
	{
		assert(ind < cachedValues_.size());

		return cachedValues_[ind];
	}

	static bool isPureComplex(String t)
	{
		if (t == "i")
			return true;

		const SizeType n = t.length();
		if (n < 2)
			return false;
		String tmp = t.substr(0, n - 1);
		return isRealScalar(tmp);
	}

	static ComplexOrRealType pureComplex(String t)
	{
		static const bool isComplex = IsComplexNumber::True;
		if (!isComplex)
			err("i = sqrt(-1) found in code path that is real\n");

		CpmlxOrReal cmplxOrReal(t);
		return cmplxOrReal.value();
	}

	static bool isRealScalar(String termStr)
	{
		const SizeType n = termStr.length();
		if (n == 0)
			err("CanonicalExpression: term must not be empty\n");

		for (SizeType i = 0; i < n; ++i) {
			char c = termStr[i];
			bool isDigit = (c >= '0' && c <= '9');
			if (c == '.' || c == '-' || c == '+' || isDigit)
				continue;
			return false;
		}

		return true;
	}

private:

	ComplexOrRealType simpleArithmetics(String str)
	{
		replaceAll(str, "pi", ttos(M_PI));

		VectorStringType ve;
		split(ve, str, ":");

		typedef PlusMinusMultiplyDivide
		    PrimitivesType;
		PrimitivesType primitives;
		ExpressionForAST expresionForAST(ve,
		    primitives);
		return expresionForAST.exec();
	}

	String str_;
	String mainBuffer_;
	VectorStringType ats_;
	VectorStringType terms_;
	VectorType cachedValues_;
};
} // namespace PsimagLite
#endif // QUASICANONICAL_H
PsimagLite-3.06/src/Random48.h000066400000000000000000000025541446452427400160560ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************

*/

#ifndef RANDOM48_H
#define RANDOM48_H
#include "Vector.h"
#include 
#include 

namespace PsimagLite
{
template 
class Random48
{

public:

	typedef long int LongType;
	typedef T value_type; // legacy name

	Random48(LongType seed, SizeType rank = 0, SizeType nprocs = 1)
	{
		srand48(seed);
		Vector::Type vOfSeeds(nprocs);
		for (SizeType i = 0; i < vOfSeeds.size(); i++)
			vOfSeeds[i] = static_cast(10000.0 * drand48());
		seed_ = vOfSeeds[rank];
		srand48(seed_);
	}

	T random() const // deprecated!!! use operator() instead
	{
		return static_cast(drand48());
	}

	T operator()() const { return static_cast(drand48()); }

	LongType seed() const { return seed_; }

	void seed(const LongType& seed) { seed_ = seed; }

private:

	LongType seed_;
}; // Random48
} // namespace PsimagLite

#endif // RANDOM48_H
PsimagLite-3.06/src/RandomForTests.h000066400000000000000000000024521446452427400173710ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************

*/

/** \ingroup PsimagLite */
/*@{*/

/*! \file RandomForTests.h
 *
 *  THIS RNG IS FOR TESTS, DO NOT USE FOR PRODUCTION, IT'S NOT RANDOM ENOUGH!!
 *
 */

#ifndef RANDOM_FOR_TESTS_H
#define RANDOM_FOR_TESTS_H
#include 
#include 
#include 
#include 

namespace PsimagLite
{
template 
class RandomForTests
{

public:

	typedef long int LongType;
	typedef T value_type; // legacy name

	RandomForTests(int seed)
	    : next_(seed)
	{
	}

	T operator()()
	{
		next_ = 16807 * (next_ % 127773) - 2836 * (next_ / 127773);
		if (next_ <= 0)
			next_ += 2147483647;
		if (next_ >= 2147483647)
			next_ = 1;
		return static_cast(next_) / 2147483647.0;
	}

private:

	int next_;
}; // RandomForTests
} // namespace PsimagLite

/*@}*/
#endif // RANDOM_FOR_TESTS_H
PsimagLite-3.06/src/RootFindingBisection.h000066400000000000000000000037071446452427400205450ustar00rootroot00000000000000
/** \ingroup PsimagLite */
/*@{*/

/*! \file RootFindingBisection.h
 *
 *  RootFindingBisection such as chemical potential
 *
 */
#ifndef ROOT_FIND_BISECT_H
#define ROOT_FIND_BISECT_H
#include "Fermi.h"
#include "Matrix.h"
#include "ProgressIndicator.h"

namespace PsimagLite
{
template 
class RootFindingBisection
{
	typedef typename FunctionType::RealType RealType;

public:

	RootFindingBisection(const FunctionType& function, RealType a = -100., RealType b = 100., SizeType maxIter = 100, RealType tolerance = 1.0e-3)
	    : function_(function)
	    , maxIter_(maxIter)
	    , tolerance_(tolerance)
	    , a_(a)
	    , b_(b)
	{
		RealType f1 = function_(a_) * function_(b_);
		if (f1 >= 0)
			throw RuntimeError(
			    "RootFindingBisection: condition not met\n");
	}

	RealType operator()() const
	{
		// INPUT: Function f, endpoint values a, b, tolerance TOL,
		//                maximum iterations NMAX
		// CONDITIONS: a < b, either f(a) < 0 and f(b) > 0 or
		//                           f(a) > 0 and f(b) < 0
		// OUTPUT: value which differs from a root of f(x)=0 by less
		// than TOL

		RealType a = a_;
		RealType b = b_;
		SizeType n = 0;
		RealType functionAtA = function_(a);
		while (n < maxIter_) {
			RealType c = (a + b) / 2; // new midpoint
			RealType tmp = function_(c);
			if (fabs(tmp) < tolerance_) { // solution found
				return c;
			}
			n++;
			if (sign(tmp) == sign(functionAtA)) {
				a = c;
				functionAtA = tmp;
			} else {
				b = c;
			}
		}

		String msg("RootFindBisection, too many iterations ");
		msg += "maximum = " + ttos(maxIter_) + " tolerance = ";
		msg += ttos(tolerance_) + " a = " + ttos(a_) + " b = " + ttos(b_) + "\n";
		throw std::runtime_error(msg);
	}

private:

	int sign(const RealType& x) const { return (x >= 0) ? 1 : -1; }

	const FunctionType& function_;
	SizeType maxIter_;
	RealType tolerance_;
	RealType a_, b_;
}; // RootFindingBisection
} // namespace PsimagLite

/*@}*/
#endif // ROOT_FIND_BISECT_H
PsimagLite-3.06/src/RungeKutta.h000066400000000000000000000121151446452427400165450ustar00rootroot00000000000000/*
Copyright (c) 2012, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]
[by K.A.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************


*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file RungeKutta.h
 *
 * authored by K.A.A
 *
 * DOC HERE FIXME
 *
 */
#ifndef RUNGE_KUTTA_H
#define RUNGE_KUTTA_H

#include "Complex.h"
#include "Matrix.h"
#include "Vector.h"
#include 

namespace PsimagLite
{

template >
class RungeKutta
{

	typedef typename ArrayType::value_type ComplexOrRealType;
	typedef typename Vector::Type VectorType;

public:

	RungeKutta(const FunctionType& f, const RealType& h)
	    : f_(f)
	    , h_(h)
	    , verbose_(false)
	{
	}

	void solveEx(typename Vector::Type& result, RealType t0, RealType t, const ArrayType& y0) const
	{
		SizeType N = static_cast(PsimagLite::real((t - t0) / h_));
		solve(result, t0, N, y0);
	}

	void solve(typename Vector::Type& result, RealType t0, SizeType N, const ArrayType& y0) const
	{
		ArrayType k1(y0), k2(y0), k3(y0), k4(y0);
		RealType w1 = 1, w2 = 2, w3 = 2, w4 = 1,
			 wtotInverse = 1.0 / 6.0;

		RealType ti = t0;
		ArrayType yi = y0;
		ArrayType tmp;
		RealType f1 = 0.5;
		for (SizeType i = 0; i < N; i++) {
			k1 <= h_* f_(ti, yi);
			tmp <= yi + k1* f1;
			k2 <= h_* f_(ti + h_ * f1, tmp);
			tmp <= yi + k2* f1;
			k3 <= h_* f_(ti + h_ * f1, tmp);
			tmp <= yi + k3;
			k4 <= h_* f_(ti + h_, tmp);

			VectorType myresult(findSizeOf(yi));
			for (SizeType j = 0; j < myresult.size(); j++)
				myresult[j] = findValueOf(yi, j);
			result.push_back(myresult);
			ti += h_;
			tmp <= (w1 * k1 + w2 * k2 + w3 * k3 + w4 * k4);
			yi += tmp * wtotInverse;
			checkNorm(yi, y0);
		}
	}

private:

	ComplexOrRealType findValueOf(const VectorType& yi, SizeType j) const
	{
		return yi[j];
	}

	ComplexOrRealType findValueOf(const Matrix& yi,
	    SizeType j) const
	{
		return yi(j, j);
	}

	SizeType findSizeOf(const VectorType& yi) const { return yi.size(); }

	SizeType findSizeOf(const Matrix& yi) const
	{
		return yi.n_row();
	}

	void checkNorm(const Matrix&,
	    const Matrix&) const
	{
	}

	void checkNorm(const VectorType& yi, const VectorType& y0) const
	{
		String s(__FILE__);
		s += " Norma not preserved\n";
		RealType norma = norm(yi);
		RealType originalNorm = norm(y0);
		if (fabs(norma - originalNorm) > 1e-4)
			std::cerr << s;
	}

	const FunctionType& f_;
	RealType h_;
	bool verbose_;
}; // class RungeKutta

} // namespace PsimagLite

/*@}*/
#endif // RUNGE_KUTTA
PsimagLite-3.06/src/SampleCRSMatrix.h000066400000000000000000000145401446452427400174360ustar00rootroot00000000000000
/*
Copyright (c) 2009, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 0.0.1]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************
*/

#ifndef SAMPLE_CRSMATRIX_HEADER_H
#define SAMPLE_CRSMATRIX_HEADER_H

#include "Sort.h"
#include "loki/TypeTraits.h"
#include 
#include  // <-- just for drand48 and srand48(seed)
#include 
#include 
#include 

namespace PsimagLite
{

template 
class SampleCRSMatrix
{

public:

	typedef T value_type;

	SampleCRSMatrix(SizeType rank)
	    : rank_(rank)
	    , rowptr_(rank + 1)
	{
	}

	SampleCRSMatrix(SizeType rank, SizeType seed, SizeType nonZeros, T maxValue)
	    : rank_(rank)
	    , rowptr_(rank + 1)
	{
		srand48(seed);
		typename Vector::Type rows, cols;
		typename Vector::Type vals;
		for (SizeType i = 0; i < nonZeros; i++) {
			// pick a row
			SizeType row = SizeType(drand48() * rank);
			// and a column
			SizeType col = SizeType(drand48() * rank);
			// and a value
			T val = drand48() * maxValue;
			rows.push_back(row);
			cols.push_back(col);
			vals.push_back(val);
		}
		// fill the matrix with this data:
		fillMatrix(rows, cols, vals);
	}

	template 
	SampleCRSMatrix(SomeIoInputType& io)
	{
		io >> rank_;
		readVector(io, rowptr_);
		readVector(io, colind_);
		readVector(io, values_);
	}

	void setRow(int n, int v) { rowptr_[n] = v; }

	void pushCol(int i) { colind_.push_back(i); }

	void pushValue(const T& value) { values_.push_back(value); }

	void matrixVectorProduct(typename Vector::Type& x,
	    const typename Vector::Type& y) const
	{
		for (SizeType i = 0; i < y.size(); i++)
			for (SizeType j = rowptr_[i]; j < rowptr_[i + 1]; j++)
				x[i] += values_[j] * y[colind_[j]];
	}

	SizeType rank() const { return rank_; }

	template 
	void save(SomeIoOutputType& io) const
	{
		io << rank_ << "\n";
		saveVector(io, rowptr_);
		saveVector(io, colind_);
		saveVector(io, values_);
	}

	SizeType getRowPtr(SizeType i) const
	{
		assert(i < rowptr_.size());
		return rowptr_[i];
	}

	SizeType getCol(SizeType i) const
	{
		assert(i < colind_.size());
		return colind_[i];
	}

	const T& getValues(SizeType i) const
	{
		assert(i < values_.size());
		return values_[i];
	}

private:

	template 
	typename EnableIf::True, void>::Type
	saveVector(SomeIoOutputType& io, const SomeVectorType& v) const
	{
		io << v.size() << "\n";
		for (SizeType i = 0; i < v.size(); i++) {
			io << v[i] << " ";
		}
		io << "\n";
	}

	template 
	typename EnableIf::True, void>::Type
	readVector(SomeIoInputType& io, SomeVectorType& v) const
	{
		int size = 0;
		io >> size;
		if (size < 0)
			throw RuntimeError("readVector: size is zero\n");
		v.resize(size);
		for (SizeType i = 0; i < v.size(); i++) {
			io >> v[i];
		}
	}

	void fillMatrix(typename Vector::Type& rows,
	    typename Vector::Type& cols,
	    typename Vector::Type& vals)
	{
		Sort::Type> s;
		typename Vector::Type iperm(rows.size());
		s.sort(rows, iperm);
		SizeType counter = 0;
		SizeType prevRow = rows[0] + 1;
		for (SizeType i = 0; i < rows.size(); i++) {
			SizeType row = rows[i];
			if (prevRow != row) {
				// add new row
				rowptr_[row] = counter++;
				prevRow = row;
			}
			colind_.push_back(cols[iperm[i]]);
			values_.push_back(vals[iperm[i]]);
		}
		SizeType lastNonZeroRow = rows[rows.size() - 1];
		for (SizeType i = lastNonZeroRow + 1; i <= rank_; i++)
			rowptr_[i] = counter;
	}

	SizeType rank_;
	typename Vector::Type rowptr_;
	typename Vector::Type colind_;
	typename Vector::Type values_;

}; // class SampleCRSMatrix

template 
std::ostream& operator<<(std::ostream& os, const SampleCRSMatrix& m)
{
	m.save(os);
	return os;
}

} // namespace PsimagLite
#endif
PsimagLite-3.06/src/SampleCRSMatrix.w000066400000000000000000000150751446452427400174610ustar00rootroot00000000000000\documentclass{report}
\usepackage[T1]{fontenc}
\usepackage{bera}

\usepackage[pdftex,usenames,dvipsnames]{color}
\usepackage{listings}
\definecolor{mycode}{rgb}{0.9,0.9,1}
\lstset{language=c++,tabsize=1,basicstyle=\scriptsize,backgroundcolor=\color{mycode}}

\usepackage{hyperref}
\usepackage{fancyhdr}
\pagestyle{fancy}
\usepackage{verbatim}
\begin{document}

%\title{The SampleCRSMatrix Class}
%\author{G.A.}
%\maketitle

\begin{comment}
@o SampleCRSMatrix.h -t
@{
/*
@i license.txt
*/
@}
\end{comment}

\section{A class to represent a sparse matrix in Compressed Row Storage (CRS)}

HEre is some boilerplate:

@o SampleCRSMatrix.h -t
@{
#ifndef SAMPLE_CRSMATRIX_HEADER_H
#define SAMPLE_CRSMATRIX_HEADER_H

#include 
#include 
#include 
#include  // <-- just for drand48 and srand48(seed)
#include "Sort.h"

namespace PsimagLite {
	@
	@
} // namespace Dmrg
#endif

@}

The CRS format puts the subsequent nonzero elements of the matrix rows
in contiguous memory locations. We create 3 vectors: one for complex numbers containing the values of the
matrix entries
and the other two for integers ($colind$ and $rowptr$).
The vector $values$ stores the values of the non-zero elements of the matrix,
as they are traversed in a row-wise fashion.
The $colind$ vector stores the column indices of the elements of the $values$
vector. That is, if $values[k] = a[i][j]$ then $colind[k] = j$.
The $rowptr$ vector stores the locations in the $values$ vector that start
a row, that is $values[k] = a[i][j]$ if $rowptr[i] \le i < rowptr[i + 1]$.
By convention, we define $rowptr[N_{dim}]$ to be equal to the number of non-zero elements,
$n_z$, in the matrix. The storage savings of this approach are significant since instead of
storing $N_{dim}^2$ elements, we need only $2n_z + N_{dim} + 1$ storage locations.\\
To illustrate how the CRS format works, consider the non-symmetric matrix defined by
\begin{equation}
	A=\left[\begin{tabular}{llllll}

	10 &  0 & 0 & 0  & -2 & 0 \\
	3 &  9 &  0 &  0 &  0 &  3 \\
	0 &  7 &  8 &  7 &  0 &  0 \\
	3 &  0 &  8 &  7  & 5 &  0 \\
	0 &   8 &  0 &  9 &  9 & 13 \\
	0 &  4 &  0 &  0 &  2&  -1 \\
\end{tabular}\right]\end{equation}

The CRS format for this matrix is then specified by the arrays:

\begin{tt}
	values = [10 -2  3  9  3  7  8  7  3 ... 9 13  4  2 -1 ]\\
	colind = [ 0  4  0  1  5  1  2  3  0 ... 4  5  1  4  5 ]\\
	rowptr = [ 0  2  5  8 12 16 19 ]\\
\end{tt}

So, this is the class:

@d theClassHere
@{
template
class SampleCRSMatrix {
public:
	typedef T value_type;
	@
	@
private:
	@
	@
}; // class SampleCRSMatrix
@}

From what we discussed above the private data is
@d privateData
@{
SizeType rank_;
typename Vector::Type rowptr_;
typename Vector::Type colind_;
typename Vector::Type values_;
@}

The constructor is
@d constructors
@{
@
@
@
@}

The empty constructor just creates an empty CRS matrix with the rank given:
@d emptyConstructor
@{
SampleCRSMatrix(SizeType rank) : rank_(rank),rowptr_(rank+1)
{
}
@}

The random constructor, takes a seed, and the number of non-zero values and fills the matrix
randomly. Note that $T$ must be a real type here:
@d randomConstructor
@{
SampleCRSMatrix(SizeType rank,T seed,SizeType nonZeros,T maxValue) : rank_(rank),rowptr_(rank+1)
{
	srand48(seed);
	typename Vector::Type rows,cols;
	typename Vector::Type vals;
	for (SizeType i=0;i
SampleCRSMatrix(SomeIoInputType& io)
{
	io>>rank_;
	readVector(io,rowptr_);
	readVector(io,colind_);
	readVector(io,values_);
}
@}
The public functions are
@d publicFunctions
@{
@
@
@
@
@
@
@}

@d setRow
@{
void setRow(int n,int v)
{
	rowptr_[n]=v;
}
@}

The function below
performs $\vec{x} = \vec{x} + A * \vec{y}$,
 where $\vec{x}$ and $\vec{y}$ are vectors and A is this sparse matrix in
 compressed row format (CRS):
 @d matrixVectorProduct
 @{
void matrixVectorProduct(typename Vector::Type& x, const typename Vector::Type& y) const
{
	for (SizeType i = 0; i < y.size(); i++)
		for (SizeType j = rowptr_[i]; j < rowptr_[i + 1]; j++)
			x[i] += values_[j] * y[colind_[j]];
}
@}

@d rank
@{
SizeType rank() const { return rank_; }
@}

@d pushCol
@{
void pushCol(int i) { colind_.push_back(i); }
@}

@d pushValue
@{
void pushValue(const T& value) { values_.push_back(value); }
@}

@d save
@{
template
void save(SomeIoOutputType& io) const
{
	io<
@
@
@}

@d saveVector
@{
template
void saveVector(SomeIoOutputType& io,const typename Vector::Type& v) const
{
	io<
void readVector(SomeIoInputType& io,typename Vector::Type& v) const
{
	int size=0;
	io>>size;
	if (size<0) throw RuntimeError("readVector: size is zero\n");
	v.resize(size);
	for (SizeType i=0;i>v[i];
	}
}
@}

@d fillMatrix
@{
void fillMatrix(typename Vector::Type& rows,typename Vector::Type& cols,
		typename Vector::Type& vals)
{
	Sort::Type > s;
    typename Vector::Type iperm(rows.size());
	s.sort(rows,iperm);
	SizeType counter = 0;
	SizeType prevRow = rows[0]+1;
	for (SizeType i=0;i
@}

@d operatorDump
@{
template
std::ostream& operator<<(std::ostream& os,const SampleCRSMatrix& m)
{
	m.save(os);
	return os;
}
@}


\end{document}

PsimagLite-3.06/src/Sort.h000066400000000000000000000024061446452427400154050ustar00rootroot00000000000000// sort algorithm example
#ifndef SORT_H_H
#define SORT_H_H
#include "Vector.h"
#include 
#include 
#include 

namespace PsimagLite
{
template 
class Sort
{
public:

	typedef typename ContainerType::value_type FieldType;
	typedef std::pair PairType;
	class Compare
	{

	public:

		Compare(const typename Vector::Type& x)
		    : x_(x)
		{
		}

		bool operator()(const PairType& x1, const PairType& x2)
		{
			return (x1.first < x2.first);
		}

	private:

		const typename Vector::Type& x_;
	};

	template 
	void sort(ContainerType& x, typename std::vector& iperm, SizeType smallSize = 0)
	{
		SizeType n = x.size();
		if (n == 0)
			return;
		// FIXME: DON'T USE smallSize, just say n=iperm.size()
		if (smallSize != 0)
			n = smallSize;
		assert(n == iperm.size());
		const ContainerType& xread = x;
		PairType onep(xread[0], 0);
		typename Vector::Type p(n, onep);
		for (SizeType i = 0; i < n; i++) {
			p[i].first = xread[i];
			p[i].second = i;
		}
		std::sort(p.begin(), p.end(), Compare(p));
		for (SizeType i = 0; i < n; i++) {
			x[i] = p[i].first;
			iperm[i] = p[i].second;
		}
	}

}; // class Sort
} // namespace PsimagLite

#endif // SORT_H_H
PsimagLite-3.06/src/SparseRow.h000066400000000000000000000106641446452427400164100ustar00rootroot00000000000000/*
Copyright (c) 2009, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup DMRG */
/*@{*/

/*! \file SparseRow.h
 *
 *  Sparse row allows one to accumulate non-zeros to a row
 *  of a CrsMatrix and add the row at the end
 */
#ifndef SPARSE_ROW_H
#define SPARSE_ROW_H

#include "Sort.h"
#include 

namespace PsimagLite
{

template 
class SparseRow
{
public:

	typedef typename CrsMatrixType::value_type ValueType;
	typedef typename Vector::Type ColumnsType;
	typedef typename Vector::Type VectorType;

	void add(SizeType col, ValueType value)
	{
		cols_.push_back(col);
		values_.push_back(value);
	}

	ValueType matrixVectorProduct(const VectorType& y) const
	{
		ValueType sum = 0;
		for (SizeType i = 0; i < cols_.size(); i++)
			sum += values_[i] * y[cols_[i]];
		return sum;
	}
	//		void clear()
	//		{
	//			cols_.clear();
	//			values_.clear();
	//		}

	SizeType finalize(CrsMatrixType& matrix)
	{
		assert(cols_.size() == values_.size());
		if (cols_.size() == 0)
			return 0;

		Sort s;
		ColumnsType iperm(cols_.size());
		s.sort(cols_, iperm);
		SizeType prevCol = cols_[0];
		SizeType counter = 0;
		ValueType value = 0;
		for (SizeType i = 0; i < cols_.size(); i++) {
			assert(cols_[i] < matrix.cols());
			if (cols_[i] == prevCol) {
				value += values_[iperm[i]];
				continue;
			}
			matrix.pushCol(prevCol);
			matrix.pushValue(value);
			counter++;
			value = values_[iperm[i]];
			prevCol = cols_[i];
		}
		matrix.pushCol(prevCol);
		matrix.pushValue(value);
		counter++;
		return counter;
	}

	ValueType finalize(const VectorType& y)
	{
		assert(cols_.size() == values_.size());
		if (cols_.size() == 0)
			return 0;

		ValueType sum = 0.0;
		for (SizeType i = 0; i < cols_.size(); i++)
			sum += values_[i] * y[cols_[i]];
		return sum;
	}

private:

	ColumnsType cols_;
	VectorType values_;

}; // class SparseRow

} // namespace PsimagLite

/*@}*/
#endif // SPARSE_ROW_H
PsimagLite-3.06/src/SparseRowCached.h000066400000000000000000000112001446452427400174630ustar00rootroot00000000000000// BEGIN LICENSE BLOCK
/*
Copyright (c) 2009, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************


*/
// END LICENSE BLOCK
/** \ingroup DMRG */
/*@{*/

/*! \file SparseRowCached.h
 *
 *  Sparse row allows one to accumulate non-zeros to a row
 *  of a CrsMatrix and add the row at the end
 */
#ifndef SPARSE_ROW_CACHED_H
#define SPARSE_ROW_CACHED_H

#include "Sort.h"
#include 

namespace PsimagLite
{

template 
class SparseRowCached
{

public:

	typedef typename CrsMatrixType::value_type ValueType;
	typedef typename Vector::Type ColumnsType;
	typedef typename Vector::Type VectorType;

	SparseRowCached(SizeType cacheSize)
	    : cols_(cacheSize)
	    , values_(cacheSize)
	    , counter_(0)
	{
	}

	void add(SizeType col, ValueType value)
	{
		/*			cols_.push_back(col);
					values_.push_back(value);*/
		SizeType cacheSize = cols_.size();
		if (counter_ >= cacheSize) {
			cacheSize *= 2;
			cols_.resize(cacheSize);
			values_.resize(cacheSize);
		}

		cols_[counter_] = col;
		values_[counter_] = value;
		counter_++;
	}

	ValueType matrixVectorProduct(const VectorType& y)
	{
		ValueType sum = 0;
		for (SizeType i = 0; i < counter_; i++)
			sum += values_[i] * y[cols_[i]];
		counter_ = 0;
		return sum;
	}
	//		void clear()
	//		{
	//			cols_.clear();
	//			values_.clear();
	//		}

	SizeType finalize(CrsMatrixType& matrix)
	{
		// assert(cols_.size()==values_.size());
		if (counter_ == 0)
			return 0;

		Sort s;
		ColumnsType iperm(counter_);
		s.sort(cols_, iperm, counter_);
		SizeType prevCol = cols_[0];
		SizeType counter = 0;
		ValueType value = 0;
		for (SizeType i = 0; i < counter_; i++) {
			if (cols_[i] == prevCol) {
				value += values_[iperm[i]];
				continue;
			}
			matrix.pushCol(prevCol);
			matrix.pushValue(value);
			counter++;
			value = values_[iperm[i]];
			prevCol = cols_[i];
		}
		matrix.pushCol(prevCol);
		matrix.pushValue(value);
		counter++;
		counter_ = 0;
		return counter;
	}

private:

	ColumnsType cols_;
	typename Vector::Type values_;
	SizeType counter_;

}; // class SparseRowCached

} // namespace PsimagLite

/*@}*/
#endif // SPARSE_ROW_CACHED_H
PsimagLite-3.06/src/SparseVector.h000066400000000000000000000235441446452427400171040ustar00rootroot00000000000000/*
Copyright (c) 2009-2012, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************


*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file SparseVector.h
 *
 *  A class to represent sparse vectors
 *
 */
#ifndef PsimagLite_SPARSEVECTOR_H
#define PsimagLite_SPARSEVECTOR_H

#include "Sort.h"
#include "Vector.h" // in PsimagLite
#include 
#include 
#include 
#include 

namespace PsimagLite
{
template 
struct SparseVector {
public:

	typedef FieldType value_type;
	typedef std::pair PairType;

	SparseVector(const typename Vector::Type& v)
	    : size_(v.size())
	    , isSorted_(false)
	{
		FieldType zerovalue = static_cast(0);
		for (SizeType i = 0; i < v.size(); i++) {
			if (v[i] != zerovalue) {
				values_.push_back(v[i]);
				indices_.push_back(i);
			}
		}
	}

	void fromChunk(const typename Vector::Type& v,
	    SizeType offset,
	    SizeType total)
	{
		resize(total);
		for (SizeType i = 0; i < v.size(); i++) {
			indices_.push_back(i + offset);
			values_.push_back(v[i]);
		}
	}

	SparseVector(SizeType n)
	    : size_(n)
	    , isSorted_(false)
	{
	}

	void resize(SizeType x)
	{
		values_.clear();
		indices_.clear();
		size_ = x;
	}

	//! adds an index (maybe the indices should be sorted at some point)
	SizeType add(int index, const FieldType& value)
	{
		indices_.push_back(index);
		values_.push_back(value);
		isSorted_ = false;
		return values_.size() - 1;
	}

	SizeType size() const { return size_; }

	void print(std::ostream& os, const String& label) const
	{
		os << label << ", ";
		os << size_ << ", ";
		os << indices_.size() << ", ";
		for (SizeType i = 0; i < indices_.size(); i++) {
			os << indices_[i] << " " << values_[i] << ",";
		}
		os << "\n";
	}

	SizeType indices() const { return indices_.size(); }

	SizeType index(SizeType x) const { return indices_[x]; }

	FieldType value(SizeType x) const { return values_[x]; }

	void toChunk(typename Vector::Type& dest, SizeType i0, SizeType total, bool test = false) const
	{
		if (test) {
			PairType firstLast = findFirstLast();
			if (i0 > firstLast.first || i0 + total < firstLast.second)
				throw RuntimeError("SparseVector::toChunk(...)"
						   " check failed\n");
		}
		dest.resize(total);
		for (SizeType i = 0; i < indices_.size(); i++)
			dest[indices_[i] - i0] = values_[i];
	}

	template 
	SizeType toChunk(typename Vector::Type& dest,
	    const SomeBasisType& parts) const
	{
		SizeType part = findPartition(parts);
		SizeType offset = parts.partition(part);
		SizeType total = parts.partition(part + 1) - offset;
		dest.resize(total);
		for (SizeType i = 0; i < total; i++)
			dest[i] = 0;
		for (SizeType i = 0; i < indices_.size(); i++)
			dest[indices_[i] - offset] = values_[i];
		return part;
	}

	template 
	SizeType findPartition(const SomeBasisType& parts) const
	{
		PairType firstLast = findFirstLast();
		SizeType ret = 0;
		for (SizeType i = 0; i < parts.partition(); i++) {
			if (firstLast.first >= parts.partition(i)) {
				ret = i;
			} else {
				break;
			}
		}
		SizeType ret2 = 1;
		for (SizeType i = 0; i < parts.partition(); i++) {
			if (firstLast.second > parts.partition(i)) {
				ret2 = i;
			} else {
				break;
			}
		}
		if (ret != ret2)
			throw RuntimeError(
			    "SparseVector::findPartition(...)"
			    "vector extends more than one partition\n");
		return ret;
	}

	template 
	SparseVector operator*=(const T& val)
	{
		for (SizeType i = 0; i < values_.size(); i++)
			values_[i] *= val;
		return *this;
	}

	SparseVector operator-=(const SparseVector& v)
	{
		for (SizeType i = 0; i < v.values_.size(); i++) {
			values_.push_back(-v.values_[i]);
			indices_.push_back(v.indices_[i]);
		}
		isSorted_ = false;
		return *this;
	}

	bool operator==(const SparseVector& v) const
	{
		assert(isSorted_);
		assert(v.isSorted_);
		for (SizeType i = 0; i < v.values_.size(); i++) {
			if (indices_[i] != v.indices_[i])
				return false;
			FieldType val = values_[i] - v.values_[i];
			if (!isAlmostZero(val, 1e-8))
				return false;
		}
		return true;
	}

	// FIXME : needs performance
	FieldType scalarProduct(const SparseVector& v) const
	{
		assert(indices_.size() == 1 || isSorted_);
		assert(v.indices_.size() == 1 || v.isSorted_);
		FieldType sum = 0;
		SizeType i = 0, j = 0, index = 0;

		for (; i < indices_.size(); i++) {
			index = indices_[i];
			for (; j < v.indices_.size(); j++) {
				if (v.indices_[j] < index)
					continue;
				if (v.indices_[j] > index)
					break;
				if (v.indices_[j] == index)
					sum += values_[i] * PsimagLite::conj(v.values_[j]);
			}
			if (j > 0)
				j--;
		}

		return sum;
	}

	bool isOne()
	{
		SizeType x = 0;
		for (SizeType i = 0; i < indices_.size(); i++) {
			if (isAlmostZero(values_[i], 1e-4))
				continue;
			x++;
			if (x > 1)
				return false;
		}
		return true;
	}

	void sort()
	{
		if (indices_.size() < 2 || isSorted_)
			return;

		Sort::Type> sort;
		typename Vector::Type iperm(indices_.size());
		sort.sort(indices_, iperm);
		typename Vector::Type values(iperm.size());
		for (SizeType i = 0; i < values_.size(); i++)
			values[i] = values_[iperm[i]];
		values_.clear();
		FieldType sum = values[0];
		SizeType prevIndex = indices_[0];
		typename Vector::Type indices;

		for (SizeType i = 1; i < indices_.size(); i++) {

			if (indices_[i] != prevIndex) {
				if (PsimagLite::norm(sum) > 1e-16) {
					values_.push_back(sum);
					indices.push_back(prevIndex);
				}
				sum = values[i];
				prevIndex = indices_[i];
			} else {
				sum += values[i];
			}
		}
		if (PsimagLite::norm(sum) > 1e-16) {
			values_.push_back(sum);
			indices.push_back(prevIndex);
		}
		indices_ = indices;
		isSorted_ = true;
	}

	void clear()
	{
		values_.clear();
		indices_.clear();
		isSorted_ = false;
	}

	template 
	friend SparseVector operator*(const T& val,
	    const SparseVector& sv);

private:

	PairType findFirstLast() const
	{
		return PairType(
		    *(std::min_element(indices_.begin(), indices_.end())),
		    *(std::max_element(indices_.begin(), indices_.end())));
	}

	typename Vector::Type values_;
	typename Vector::Type indices_;
	SizeType size_;
	bool isSorted_;
}; // class SparseVector

template 
std::ostream& operator<<(std::ostream& os, const SparseVector& s)
{
	s.print(os, "SparseVector");
	return os;
}

template 
SparseVector operator*(const T& val, const SparseVector& sv)
{
	SparseVector res = sv;
	for (SizeType i = 0; i < res.values_.size(); i++)
		res.values_[i] *= val;
	return res;
}

template 
T operator*(const SparseVector& v1, const SparseVector& v2)
{
	return v1.scalarProduct(v2);
}
} // namespace PsimagLite

namespace PsimagLite
{
template 
inline FieldType norm(const SparseVector& v)
{
	FieldType sum = 0;
	for (SizeType i = 0; i < v.indices(); i++)
		sum += PsimagLite::conj(v.value(i)) * v.value(i);
	return sqrt(sum);
}

template 
inline FieldType norm(const SparseVector>& v)
{
	std::complex sum = 0;
	for (SizeType i = 0; i < v.indices(); i++)
		sum += PsimagLite::conj(v.value(i)) * v.value(i);
	return real(sqrt(sum));
}

} // namespace PsimagLite
/*@}*/
#endif
PsimagLite-3.06/src/SpecialFunctions.cpp000066400000000000000000000010401446452427400202530ustar00rootroot00000000000000#include "SpecialFunctions.h"

namespace PsimagLite
{
std::complex LnGammaFunction(const std::complex& z)
{
	GslWrapper gslWrapper;
	GslWrapper::gsl_sf_result lnr;
	GslWrapper::gsl_sf_result arg;
	gslWrapper.gsl_sf_lngamma_complex_e(PsimagLite::real(z),
	    PsimagLite::imag(z),
	    &lnr,
	    &arg);
	return std::complex(lnr.val, arg.val);
}

double Ci(const double& x)
{
	GslWrapper gslWrapper;
	GslWrapper::gsl_sf_result result;
	gslWrapper.gsl_sf_Ci_e(x, &result);
	return result.val;
}

} // namespace PsimagLite
PsimagLite-3.06/src/SpecialFunctions.h000066400000000000000000000004161446452427400177260ustar00rootroot00000000000000#ifndef PSI_SPECIAL_FUNCTIONS_H
#define PSI_SPECIAL_FUNCTIONS_H
#include "GslWrapper.h"

namespace PsimagLite
{

std::complex LnGammaFunction(const std::complex&);

double Ci(const double& x);

} // namespace PsimagLite
#endif // PSI_SPECIAL_FUNCTIONS_H
PsimagLite-3.06/src/Stack.h000066400000000000000000000076111446452427400155260ustar00rootroot00000000000000/*
Copyright (c) 2009 , UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************


*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file Stack.h
 *
 *  std::stack companions
 */

#ifndef PSIMAGLITE_STACK_H_
#define PSIMAGLITE_STACK_H_
#include "AllocatorCpu.h"
#include "Vector.h"
#include 

namespace PsimagLite
{

template 
class Stack
{

	typedef std::deque::Type> DequeType_;

public:

	typedef std::stack Type;
}; // class Stack

template 
class IsStackLike
{
public:

	enum { True = false };
};

template 
class IsStackLike::Type>>>
{
public:

	enum { True = true };
};

template 
typename EnableIf::True, std::ostream>::Type&
operator<<(std::ostream& os, const StackType& st)
{
	StackType st2 = st;
	os << st2.size() << "\n";
	while (!st2.empty()) {
		typename StackType::value_type x = st2.top();
		os << x << "\n";
		st2.pop();
	}
	return os;
}

template 
typename EnableIf::True, std::istream>::Type&
operator>>(std::istream& is, StackType& x)
{
	typedef typename StackType::value_type ValueType;
	typename Vector::Type tmpVec;
	is >> tmpVec;
	for (int i = tmpVec.size() - 1; i >= 0; i--) {
		x.push(tmpVec[i]);
	}
	return is;
}

} // namespace PsimagLite

/*@}*/
#endif // PSIMAGLITE_STACK_H_
PsimagLite-3.06/src/SumDecomposition.h000066400000000000000000000032211446452427400177530ustar00rootroot00000000000000#ifndef PSI_SUM_DECOMPOSITION_H
#define PSI_SUM_DECOMPOSITION_H

#include "Vector.h"
#include 
#include 
#include 
#include 

namespace PsimagLite
{

class SumDecomposition
{

	typedef Vector::Type VectorSizeType;

public:

	enum SelEnum { SEL_ALL,
		SEL_SIZE,
		SEL_INDEX };

	SumDecomposition(SizeType total, SizeType sum, SelEnum sel = SEL_ALL, int selection = 0)
	    : sum_(sum)
	    , sel_(sel)
	    , selection_(selection)
	    , size_(0)
	{
		VectorSizeType data(total, 0);
		reentrant1_(data, sum, 0);
	}

	SizeType size() const { return size_; }

	SizeType storedSize() const { return data_.size(); }

	const VectorSizeType& operator()(SizeType i) const
	{
		if (i < data_.size())
			return data_[i];
		String msg("SumDecomposition::operator():");
		throw RuntimeError(msg + " requested index is too big\n");
	}

private:

	void reentrant1_(VectorSizeType& data, SizeType n, SizeType x)
	{
		SizeType sum = 0;
		if (x >= data.size()) {
			if (std::accumulate(data.begin(), data.end(), sum) != sum_)
				return;
			bool b1 = (sel_ == SEL_ALL);
			bool b2 = (sel_ == SEL_INDEX && selection_ == size_);
			if (b1 || b2)
				data_.push_back(data);
			size_++;
			return;
		}

		for (SizeType i = 0; i <= n; ++i) {
			data[x] = i;
			reentrant1_(data, n - i, x + 1);
		}
	}

	SizeType sum_;
	SelEnum sel_;
	int selection_;
	int size_;
	Vector::Type data_;
};

std::ostream& operator<<(std::ostream& os, const SumDecomposition& sd)
{
	os << sd.storedSize() << "\n";
	for (SizeType i = 0; i < sd.storedSize(); ++i)
		os << sd(i) << "\n";

	return os;
}

} // namespace PsimagLite

#endif // PSI_SUM_DECOMPOSITION_H
PsimagLite-3.06/src/Svd.h000066400000000000000000000057051446452427400152170ustar00rootroot00000000000000#ifndef SVD_H
#define SVD_H
#include "Matrix.h"
#include 
#include 
#include 

namespace PsimagLite
{

template 
class Svd
{

public:

	typedef typename Real::Type RealType;

	Svd(String name = "gesdd")
	    : name_(name)
	{
	}

	bool canTryAgain() const { return (name_ == "gesdd"); }

	String name() const { return name_; }

	void operator()(char jobz, Matrix& a, typename Vector::Type& s, Matrix& vt)
	{
		if (jobz != 'A' && jobz != 'S') {
			String msg("svd: jobz must be either A or S");
			String jobzString = " ";
			jobzString[0] = jobz;
			throw RuntimeError(msg + ", not " + jobzString + "\n");
		}

		int m = a.rows();
		int n = a.cols();
		int lda = m;
		int min = (m < n) ? m : n;

		s.resize(min);
		int ldu = m;
		int ucol = (jobz == 'A') ? m : min;
		Matrix u(ldu, ucol);
		int ldvt = (jobz == 'A') ? n : min;
		vt.resize(ldvt, n);
		int lrwork = 2.0 * min * std::max(5 * min + 7, 2 * std::max(m, n) + 2 * min + 1);
		typename Vector::Type>::Type
		    rwork(lrwork, 0.0);

		typename Vector::Type work(100, 0);
		int info = 0;
		Vector::Type iwork(8 * min, 0);

		// query optimal work
		int lwork = -1;
		mycall(&jobz, &m, &n, &(a(0, 0)), &lda, &(s[0]), &(u(0, 0)), &ldu, &(vt(0, 0)), &ldvt, &(work[0]), &lwork, &(rwork[0]), &(iwork[0]), &info);
		if (info != 0) {
			String str(__FILE__);
			str += " svd(...) failed at workspace size calculation ";
			str += "with info=" + ttos(info) + "\n";
			throw RuntimeError(str.c_str());
		}

		RealType lworkReal = PsimagLite::real(work[0]);
		lwork = static_cast(lworkReal) + (m + n) * 256;
		work.resize(lwork + 10);

		// real work:
		mycall(&jobz, &m, &n, &(a(0, 0)), &lda, &(s[0]), &(u(0, 0)), &ldu, &(vt(0, 0)), &ldvt, &(work[0]), &lwork, &(rwork[0]), &(iwork[0]), &info);
		if (info != 0) {
			if (info < 0)
				throw RuntimeError(String(__FILE__) + ": " + ttos(__LINE__) + " info= " + ttos(info));
			if (info > 0)
				std::cerr << "WARNING " << __FILE__ << ": "
					  << __LINE__ << " info= " << info
					  << "\n";
		}

		a = u;
	}

private:

	void mycall(char* jobz, int* m, int* n,
	    ComplexOrRealType* a, // T*,
	    int* lda,
	    RealType* s,
	    ComplexOrRealType* u, // T*,
	    int* ldu,
	    ComplexOrRealType* vt, // T*,
	    int* ldvt,
	    ComplexOrRealType* work, // T*,
	    int* lwork,
	    RealType* rwork, // nothing
	    int* iwork,
	    int* info)
	{
		if (name_ == "gesdd") {
			psimag::LAPACK::GESDD(jobz, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, rwork, iwork, info);
		} else if (name_ == "gesvd") {
			psimag::LAPACK::GESVD(jobz, jobz, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, rwork, info);
		} else {
			throw PsimagLite::RuntimeError("Unknown backend " + name_ + "\n");
		}
	}

	Svd(const Svd&);

	Svd& operator=(const Svd&);

	String name_;
};

} // namespace PsimagLite
#endif // SVD_H
PsimagLite-3.06/src/TridiagonalMatrix.cpp000066400000000000000000000026071446452427400204360ustar00rootroot00000000000000#include "TridiagonalMatrix.h"

namespace PsimagLite
{

template <>
void TridiagonalMatrix::diag2(
    TridiagonalMatrix::VectorRealType& eigs,
    SizeType nn) const
{
	char jobz = 'N';
	int n = nn;
	TridiagonalMatrix::VectorType z(1, 0);
	int lz = 1;
	int lwork = 10;
	int liwork = 10;
	int info = 0;
	std::vector iwork(liwork);
	TridiagonalMatrix::VectorType work(lwork);
	TridiagonalMatrix::VectorType e = b_;
	eigs = a_;

	psimag::LAPACK::dstedc_(&jobz, &n, &(eigs[0]), &(e[1]), &(z[0]), &lz, &(work[0]), &lwork, &(iwork[0]), &liwork, &info);

	if (info == 0)
		return;
	std::cerr << "dstedc_ failed with info = " << info << "\n";
	throw RuntimeError("dstedc_ FAILED\n");
}

template <>
void TridiagonalMatrix::diag2(
    TridiagonalMatrix::VectorRealType& eigs,
    SizeType nn) const
{
	char jobz = 'N';
	int n = nn;
	TridiagonalMatrix::VectorType z(1, 0);
	int lz = 1;
	int lwork = 10;
	int liwork = 10;
	int info = 0;
	std::vector iwork(liwork);
	TridiagonalMatrix::VectorType work(lwork);
	TridiagonalMatrix::VectorType e = b_;
	eigs = a_;

	psimag::LAPACK::sstedc_(&jobz, &n, &(eigs[0]), &(e[1]), &(z[0]), &lz, &(work[0]), &lwork, &(iwork[0]), &liwork, &info);

	if (info == 0)
		return;
	std::cerr << "sstedc_ failed with info = " << info << "\n";
	throw RuntimeError("dstedc_ FAILED\n");
}

} // namespace PsimagLite
PsimagLite-3.06/src/TridiagonalMatrix.h000066400000000000000000000150311446452427400200760ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]
[by G.A., Oak Ridge National Laboratory]

UT Battelle Open Source Software License 11242008

OPEN SOURCE LICENSE

Subject to the conditions of this License, each
contributor to this software hereby grants, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), a
perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to use, copy,
modify, merge, publish, distribute, and/or sublicense
copies of the Software.

1. Redistributions of Software must retain the above
copyright and license notices, this list of conditions,
and the following disclaimer.  Changes or modifications
to, or derivative works of, the Software should be noted
with comments and the contributor and organization's
name.

2. Neither the names of UT-Battelle, LLC or the
Department of Energy nor the names of the Software
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission of UT-Battelle.

3. The software and the end-user documentation included
with the redistribution, with or without modification,
must include the following acknowledgment:

"This product includes software produced by UT-Battelle,
LLC under Contract No. DE-AC05-00OR22725  with the
Department of Energy."

*********************************************************
DISCLAIMER

THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER, CONTRIBUTORS, UNITED STATES GOVERNMENT,
OR THE UNITED STATES DEPARTMENT OF ENERGY BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED
STATES DEPARTMENT OF ENERGY, NOR THE COPYRIGHT OWNER, NOR
ANY OF THEIR EMPLOYEES, REPRESENTS THAT THE USE OF ANY
INFORMATION, DATA, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS.

*********************************************************

*/
/** \ingroup DMRG */
/*@{*/

/*! \file TridiagonalMatrix.h
 *
 *  A struct represent a tridiagonal matrix
 */
#ifndef TRIDIAGONAL_MATRIX_H
#define TRIDIAGONAL_MATRIX_H
#include "Matrix.h"

namespace PsimagLite
{

template 
class TridiagonalMatrix
{

	typedef typename Real::Type RealType;

	static const bool diagWithLapack_ = true;

public:

	typedef typename Vector::Type VectorType;
	typedef typename Vector::Type VectorRealType;
	typedef FieldType value_type;

	TridiagonalMatrix() { }

	template 
	TridiagonalMatrix(IoInputType& io)
	{
		io.read(a_, "#Avector");
		io.read(b_, "#Bvector");
	}

	template 
	void write(IoOutputType& io) const
	{
		io.write(a_, "#Avector");
		io.write(b_, "#Bvector");
	}

	void resize(SizeType n, FieldType value)
	{
		resize(n);
		for (SizeType i = 0; i < n; i++)
			a_[i] = b_[i] = value;
	}

	void resize(SizeType n)
	{
		assert(n > 0);
		a_.resize(n);
		b_.resize(n);
	}

	FieldType& a(SizeType i)
	{
		assert(i < a_.size());
		return a_[i];
	}

	FieldType& b(SizeType i)
	{
		assert(i < b_.size());
		return b_[i];
	}

	const FieldType& a(SizeType i) const
	{
		assert(i < a_.size());
		return a_[i];
	}

	const FieldType& b(SizeType i) const
	{
		assert(i < b_.size());
		return b_[i];
	}

	template 
	void buildDenseMatrix(SomeMatrixType& m, SizeType n = 0) const
	{
		if (n == 0)
			n = a_.size();
		m.resize(n, n, 0);
		for (SizeType i = 0; i < n - 1; ++i) {
			m(i, i) = a_[i];
			m(i, i + 1) = b_[i + 1];
			m(i + 1, i) = PsimagLite::conj(b_[i + 1]);
		}

		m(n - 1, n - 1) = a_[n - 1];
	}

	void diag(VectorRealType& eigs, SizeType nn) const
	{
		if (diagWithLapack_)
			diag2(eigs, nn);
		else
			ground(eigs, nn);
	}

	void push(const FieldType& a, const FieldType& b)
	{
		a_.push_back(a);
		b_.push_back(b);
	}

	SizeType size() const { return a_.size(); }

private:

	void diag2(VectorRealType&, SizeType) const;

	void ground(VectorRealType& groundD, SizeType nn) const
	{
		const int n = nn;

		groundD.resize(n);
		groundAllocations(n);

		const long int maxCounter = 10000;

		assert(a_.size() >= nn && b_.size() >= nn);
		for (SizeType i = 0; i < nn; ++i) {
			groundD[i] = a_[i];
			groundE_[i] = b_[i];
		}

		RealType s = 0;
		long int intCounter = 0;
		int m = 0;
		int l = 0;
		for (; l < n; l++) {
			do {
				intCounter++;
				if (intCounter > maxCounter) {
					std::cerr << "lanczos: ground: "
						     "premature exit ";
					std::cerr << "(may indicate an "
						     "internal error)\n";
					break;
				}

				for (m = l; m < n - 1; m++) {
					RealType dd = fabs(groundD[m]) + fabs(groundD[m + 1]);
					if ((fabs(groundE_[m]) + dd) == dd)
						break;
				}

				if (m != l) {
					RealType g = (groundD[l + 1] - groundD[l]) / (2.0 * groundE_[l]);
					RealType r = sqrt(g * g + 1.0);
					g = groundD[m] - groundD[l] + groundE_[l] / (g + (g >= 0 ? fabs(r) : -fabs(r)));
					RealType p = 0.0;
					RealType c = 1.0;
					int i = m - 1;
					for (s = 1.0; i >= l; i--) {
						RealType f = s * groundE_[i];
						RealType h = c * groundE_[i];
						groundE_[i + 1] = (r = sqrt(f * f + g * g));
						if (r == 0.0) {
							groundD[i + 1] -= p;
							groundE_[m] = 0.0;
							break;
						}

						s = f / r;
						c = g / r;
						g = groundD[i + 1] - p;
						r = (groundD[i] - g) * s + 2.0 * c * h;
						groundD[i + 1] = g + (p = s * r);
						g = c * r - h;
					}

					if (r == 0.0 && i >= l)
						continue;
					groundD[l] -= p;
					groundE_[l] = g;
					groundE_[m] = 0.0;
				}
			} while (m != l);
		}

		std::sort(groundD.begin(), groundD.end());

		if (intCounter > maxCounter)
			throw RuntimeError(String(__FILE__) + "::ground(): internal error\n");
	}

	void groundAllocations(SizeType n) const
	{
		if (groundE_.size() != n) {
			groundE_.clear();
			groundE_.resize(n);
		}
	}

	VectorRealType a_;
	VectorRealType b_;
	mutable VectorRealType groundE_;
}; // class TridiagonalMatrix
} // namespace PsimagLite

/*@}*/
#endif
PsimagLite-3.06/src/TypeToString.h000066400000000000000000000007341446452427400170730ustar00rootroot00000000000000
/* PsimagLite */
/* See LICENSE for licensing details and disclaimers */
#ifndef TYPE_TO_STRING_H
#define TYPE_TO_STRING_H

#include "AllocatorCpu.h"
#include 

namespace PsimagLite
{
template 
String typeToString(T t)
{
	std::stringstream ss;
	String str;
	ss.precision(10);
	ss << t;
	ss >> str;
	return str;
}
} // namespace PsimagLite

template 
PsimagLite::String ttos(T t)
{
	return PsimagLite::typeToString(t);
}

#endif // TYPE_TO_STRING_H
PsimagLite-3.06/src/Vector.h000066400000000000000000000326501446452427400157240ustar00rootroot00000000000000/*
Copyright (c) 2009-2013, UT-Battelle, LLC
All rights reserved

[PsimagLite, Version 1.0.0]

*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.

Please see full open source license included in file LICENSE.
*********************************************************

*/
/** \ingroup PsimagLite */
/*@{*/

/*! \file Vector.h
 *
 *
 */

#ifndef PSIVECTOR_H_
#define PSIVECTOR_H_

#include "../loki/TypeTraits.h"
#include "AllocatorCpu.h"
#include "Complex.h"
#include 
#include 
#include 

namespace PsimagLite
{

template 
struct TypesEqual {
	enum { True = false };
};

template 
struct TypesEqual {
	enum { True = true };
};

template 
struct IsInputLike {
	enum { True = false };
};

template 
struct IsOutputLike {
	enum { True = false };
};

template 
class IsVectorLike
{
public:

	enum { True = false };
};

template 
class IsVectorLike::Type>>
{
public:

	enum { True = true };
};

} // namespace PsimagLite

namespace std
{

template 
istream& operator>>(istream& is, pair& v)
{
	is >> v.first;
	is >> v.second;
	return is;
}

template 
X operator*(const vector& v, const vector& w)
{
	if (v.size() != w.size())
		throw std::runtime_error("operator*\n");

	X result = 0;
	for (SizeType i = 0; i < v.size(); i++)
		result += v[i] * PsimagLite::conj(w[i]);
	return result;
}

template 
vector operator*(const vector, AA>& v1,
    const vector& v2)
{
	vector v3(v2.size());
	for (SizeType i = 0; i < v3.size(); i++) {
		v3[i] = 0;
		for (SizeType j = 0; i < v2.size(); j++)
			v3[i] += v1[i][j] * v2[j];
	}
	return v3;
}
// closure

struct ClosureOperations {

	enum { OP_PLUS,
		OP_MINUS,
		OP_MULT,
		OP_DIVIDE,
		OP_CONJ };
};

template 
class ClosureOperator
{

public:

	ClosureOperator(const T1& v1, const T2& v2)
	    : r1(v1)
	    , r2(v2)
	{
	}

	const T1& r1;
	const T2& r2;
};

template 
struct IsClosureLike {

	enum { True = false };
};

template 
struct IsClosureLike> {

	enum { True = true };
};

// vector * scalar
template 
ClosureOperator, ClosureOperations::OP_MULT>
operator*(const T1& v1, const vector& v2)
{
	return ClosureOperator, ClosureOperations::OP_MULT>(
	    v1, v2);
}

// vector * scalar
template 
typename PsimagLite::EnableIf<
    IsClosureLike::True || IsClosureLike::True,
    ClosureOperator>::Type
operator*(const T1& v1, const T2& v2)
{
	return ClosureOperator(v1, v2);
}

template 
typename PsimagLite::EnableIf::True, void>::Type
operator<=(
    vector& v,
    const ClosureOperator, ClosureOperations::OP_MULT>& c)
{
	v = c.r2;
	for (SizeType i = 0; i < v.size(); i++)
		v[i] *= c.r1;
}

template 
typename PsimagLite::EnableIf::True && PsimagLite::IsNumber::True,
    void>::Type
operator<=(
    vector& v,
    const ClosureOperator<
	T1,
	ClosureOperator, ClosureOperations::OP_MULT>,
	ClosureOperations::OP_MULT>& c)
{
	v = c.r2.r2;
	T2 tmp = c.r1 * c.r2.r1;
	for (SizeType i = 0; i < v.size(); i++)
		v[i] *= tmp;
}

template 
ClosureOperator, ClosureOperations::OP_MULT>
operator*(const vector& v2, const T1& v1)
{
	return v1 * v2;
}

// vector + vector
template 
ClosureOperator, vector, ClosureOperations::OP_PLUS>
operator+(const vector& v1, const vector& v2)
{
	return ClosureOperator, vector, ClosureOperations::OP_PLUS>(v1, v2);
}

template 
typename PsimagLite::EnableIf<
    IsClosureLike::True || IsClosureLike::True,
    ClosureOperator>::Type
operator+(const T1& v1, const T2& v2)
{
	return ClosureOperator(v1, v2);
}

template 
void operator<=(vector& v,
    const ClosureOperator, vector, ClosureOperations::OP_PLUS>& c)
{
	v.resize(c.r1.size());
	for (SizeType i = 0; i < v.size(); i++)
		v[i] = c.r1[i] + c.r2[i];
}

template 
void operator<=(
    vector& v,
    const ClosureOperator<
	vector,
	ClosureOperator, ClosureOperations::OP_MULT>,
	ClosureOperations::OP_PLUS>& c)
{
	v.resize(c.r1.size());
	for (SizeType i = 0; i < v.size(); i++)
		v[i] = c.r1[i] + c.r2.r1 * c.r2.r2[i];
}

template 
void operator<=(
    vector& v,
    const ClosureOperator<
	ClosureOperator, ClosureOperations::OP_MULT>,
	vector,
	ClosureOperations::OP_PLUS>& c)
{
	v.resize(c.r2.size());
	for (SizeType i = 0; i < v.size(); i++)
		v[i] = c.r1.r1 * c.r1.r2[i] + c.r2[i];
}

template 
void operator<=(
    vector& v,
    const ClosureOperator, vector, ClosureOperations::OP_PLUS>,
	ClosureOperations::OP_MULT>& c)
{
	v.resize(c.r2.r2.size());
	for (SizeType i = 0; i < v.size(); i++)
		v[i] = c.r1 * (c.r2.r1[i] + c.r2.r2[i]);
}

template 
void operator<=(
    vector& v,
    const ClosureOperator<
	ClosureOperator<
	    ClosureOperator<
		ClosureOperator, ClosureOperations::OP_MULT>,
		ClosureOperator, ClosureOperations::OP_MULT>,
		ClosureOperations::OP_PLUS>,
	    ClosureOperator, ClosureOperations::OP_MULT>,
	    ClosureOperations::OP_PLUS>,
	ClosureOperator, ClosureOperations::OP_MULT>,
	ClosureOperations::OP_PLUS>& c)
{
	v.resize(c.r2.r2.size());
	T1 m1 = c.r2.r1;
	T1 m2 = c.r1.r2.r1;
	T1 m3 = c.r1.r1.r2.r1;
	T1 m4 = c.r1.r1.r1.r1;
	const vector& k1 = c.r2.r2;
	const vector& k2 = c.r1.r2.r2;
	const vector& k3 = c.r1.r1.r2.r2;
	const vector& k4 = c.r1.r1.r1.r2;
	for (SizeType i = 0; i < v.size(); i++)
		v[i] = m1 * k1[i] + m2 * k2[i] + m3 * k3[i] + m4 * k4[i];
}

// vector - vector
template 
ClosureOperator, vector, ClosureOperations::OP_MINUS>
operator-(const vector& v1, const vector& v2)
{
	return ClosureOperator, vector, ClosureOperations::OP_MINUS>(v1, v2);
}

template 
typename PsimagLite::EnableIf<
    IsClosureLike::True || IsClosureLike::True,
    ClosureOperator>::Type
operator-(const T1& v1, const T2& v2)
{
	return ClosureOperator(v1, v2);
}

template 
void operator<=(vector& v,
    const ClosureOperator, vector, ClosureOperations::OP_MINUS>& c)
{
	v.resize(c.r1.size());
	for (SizeType i = 0; i < v.size(); i++)
		v[i] = c.r1[i] - c.r2[i];
}

template 
void operator<=(
    vector& v,
    const ClosureOperator<
	vector,
	ClosureOperator, ClosureOperations::OP_MULT>,
	ClosureOperations::OP_MINUS>& c)
{
	v.resize(c.r1.size());
	for (SizeType i = 0; i < v.size(); i++)
		v[i] = c.r1[i] - c.r2.r1 * c.r2.r2[i];
}

template 
void operator<=(
    vector& v,
    const ClosureOperator, vector, ClosureOperations::OP_MINUS>,
	ClosureOperations::OP_MULT>& c)
{
	v.resize(c.r2.r2.size());
	for (SizeType i = 0; i < v.size(); i++)
		v[i] = c.r1 * (c.r2.r1[i] - c.r2.r2[i]);
}

template 
void operator<=(
    vector& v,
    const ClosureOperator<
	ClosureOperator<
	    std::vector,
	    ClosureOperator, ClosureOperations::OP_MULT>,
	    ClosureOperations::OP_MINUS>,
	ClosureOperator, ClosureOperations::OP_MULT>,
	ClosureOperations::OP_PLUS>& c)
{
	T1 m2 = c.r1.r2.r1;
	T1 m3 = c.r2.r1;
	const vector& k1 = c.r1.r1;
	const vector& k2 = c.r1.r2.r2;
	const vector& k3 = c.r2.r2;

	v.resize(k1.size());
	for (SizeType i = 0; i < v.size(); i++)
		v[i] = k1[i] - m2 * k2[i] + m3 * k3[i];
}

// operator+=
template 
vector operator+=(vector& v,
    const vector& w)
{
	for (SizeType i = 0; i < w.size(); i++)
		v[i] += w[i];
	return v;
}

template 
vector operator+=(
    vector& v,
    const ClosureOperator, ClosureOperations::OP_MULT>& w)
{
	for (SizeType i = 0; i < v.size(); i++)
		v[i] += w.r1 * w.r2[i];
	return v;
}

// operator-=
template 
vector operator-=(vector& v,
    const vector& w)
{
	for (SizeType i = 0; i < w.size(); i++)
		v[i] -= w[i];
	return v;
}

template 
vector operator-=(
    vector& v,
    const ClosureOperator, ClosureOperations::OP_MULT>& w)
{
	for (SizeType i = 0; i < v.size(); i++)
		v[i] -= w.r1 * w.r2[i];
	return v;
}

// operator*=
template 
vector operator*=(vector& v, const T2& t2)
{
	for (SizeType i = 0; i < v.size(); i++)
		v[i] *= t2;
	return v;
}

template 
vector operator/=(vector& v, const T2& t2)
{
	for (SizeType i = 0; i < v.size(); i++)
		v[i] /= t2;
	return v;
}

// end of closure

template 
T scalarProduct(const vector& v1, const vector& v2)
{
	T result = 0.0;
	const SizeType n = v1.size();
	if (n != v2.size())
		throw PsimagLite::RuntimeError(
		    "scalarProduct of vectors of different size\n");
	for (SizeType i = 0; i < n; i++)
		result += PsimagLite::conj(v1[i]) * v2[i];
	return result;
}

template 
ostream& operator<<(ostream& s, const vector& v)
{
	s << v.size() << "\n";
	for (SizeType i = 0; i < v.size(); i++)
		s << v[i] << "\n";
	return s;
}

template 
ostream& operator<<(ostream& s, const vector, A>& v)
{
	s << v.size() << "\n";
	for (SizeType i = 0; i < v.size(); i++)
		s << v[i].first << " " << v[i].second << "\n";
	return s;
}

template 
istream& operator>>(istream& is, vector& v)
{
	int xsize = 0;
	is >> xsize;
	if (xsize < 0)
		throw PsimagLite::RuntimeError(">> vector: size is negative\n");
	v.resize(xsize);
	for (SizeType i = 0; i < SizeType(xsize); i++) {
		is >> v[i];
	}
	return is;
}
} // namespace std

namespace PsimagLite
{

template 
class Vector
{
public:

	typedef std::vector::Type> Type;
}; // class Vector

template <>
class Vector
{
public:

	typedef std::vector::Type> Type;
}; // class Vector

// change this when using PsimagLite::Vector:
template 
void vectorPrint(const std::vector& v, char const* name, std::ostream& s)
{
	for (SizeType i = 0; i < v.size(); i++)
		s << name << "[" << i << "]=" << v[i] << std::endl;
}

template 
X norm(const std::vector& v)
{
	return sqrt(v * v);
}

template 
typename EnableIf::isFloat, X>::Type
norm(const std::vector, A>& v)
{
	std::complex x = v * v;
	if (fabs(std::imag(x)) > 1e-5)
		throw RuntimeError("Norm isn't real\n");
	return sqrt(std::real(x));
}

template 
void randomizeVector(typename Vector::Type& v,
    const X& a,
    const X& b,
    const RandomType& r)
{
	for (SizeType i = 0; i < v.size(); i++)
		v[i] = a + b * r.random();
}

template 
int indexOrMinusOne(const std::vector& natBasis, Y const& v)
{
	typename std::vector::const_iterator x = find(natBasis.begin(), natBasis.end(), v);
	if (x == natBasis.end())
		return -1;
	return x - natBasis.begin();
}

template 
typename EnableIf::True,
    typename SomeVectorType::value_type>::Type
sum(SomeVectorType& v)
{
	typename SomeVectorType::value_type tmp = 0;
	for (size_t i = 0; i < v.size(); i++) {
		tmp += v[i];
	}
	return tmp;
}

template 
class IsPairLike
{
public:

	enum { True = false };
};

template 
class IsPairLike>
{
public:

	enum { True = true };
};

inline String basenameOf(String s)
{
	int j = 0;
	SizeType l = s.length();
	for (SizeType i = 0; i < l; ++i) {
		j = l - i - 1;
		const char letter = s[j];
		if (letter == '.')
			break;
	}

	return s.substr(0, l - j);
}

} // namespace PsimagLite

/*@}*/
#endif // PSIVECTOR_H_
PsimagLite-3.06/src/Version.h000066400000000000000000000001041446452427400160740ustar00rootroot00000000000000#ifndef PSIMAGLITE_VERSION
#define PSIMAGLITE_VERSION "3.06"
#endif