pax_global_header00006660000000000000000000000064141460370510014513gustar00rootroot0000000000000052 comment=1cdeb4530c66cd41bd0c59af9ad2ecb1069ca010 PsimagLite-3.02/000077500000000000000000000000001414603705100134755ustar00rootroot00000000000000PsimagLite-3.02/ChangeLog.txt000066400000000000000000000256271414603705100161010ustar00rootroot000000000000002021-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.02/LICENSE000066400000000000000000000067741414603705100145200ustar00rootroot00000000000000Copyright (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.02/PolicyRegardingRegressions.txt000066400000000000000000000032521414603705100215460ustar00rootroot00000000000000MEMO: 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.02/PsimagDoc/000077500000000000000000000000001414603705100153435ustar00rootroot00000000000000PsimagLite-3.02/PsimagDoc/README000066400000000000000000000052071414603705100162270ustar00rootroot00000000000000Introducing 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.02/PsimagDoc/psimagdoc.pl000066400000000000000000000063251414603705100176540ustar00rootroot00000000000000#!/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.02/README.md000066400000000000000000000041401414603705100147530ustar00rootroot00000000000000 # 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.02/TestSuite/000077500000000000000000000000001414603705100154265ustar00rootroot00000000000000PsimagLite-3.02/TestSuite/OracleCreator.pl000066400000000000000000000006261414603705100205140ustar00rootroot00000000000000#!/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.02/TestSuite/README000066400000000000000000000126501414603705100163120ustar00rootroot00000000000000PsimagLite 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.02/TestSuite/TestSuiteGlobals.pm000066400000000000000000000377441414603705100212400ustar00rootroot00000000000000#! /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.02/doc/PsimagLiteLogo.png000066400000000000000000002010621414603705100176300ustar00rootroot00000000000000‰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.02/doc/honeycomb.tex000066400000000000000000000035271414603705100167560ustar00rootroot00000000000000\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.02/doc/manual.bbl000066400000000000000000000000001414603705100161660ustar00rootroot00000000000000PsimagLite-3.02/doc/manual.ptex000066400000000000000000000217351414603705100164310ustar00rootroot00000000000000\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.02/doc/tutorial.ptex000066400000000000000000000125051414603705100170120ustar00rootroot00000000000000\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 testMemResolv1 sumDecomposition calculator closuresTest base64test checkRunId testLanczos include Makefile.dep PsimagLite-3.02/drivers/TestMemResolv1.h000066400000000000000000000030441414603705100201570ustar00rootroot00000000000000#ifndef TEST_MEM_RESOLV_1_H #define TEST_MEM_RESOLV_1_H #include #include #include "MemResolv.h" #include "IsClass.h" 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= "< #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: "< ParallelizerType; PsimagLite::CodeSectionParams csp(nthreads, 1, true, 0); ParallelizerType threadObject(csp); HelperType helper(ntasks, nthreads); std::cout<<"Using "< #include #include #include #include "Vector.h" #include "AkimaSpline.h" 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>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 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: "<::Type v; fin.read(v,"MyVector"); std::cout<<"MyVector\n"; std::cout< m; fin.read(m, "MyMatrix"); std::cout<<"MyMatrix"; std::cout<::Type m(10); srand48(3490201); for (SizeType i=0;i a(10,20); for (SizeType i=0;iPairType; 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="< ComplexOrRealType; #else typedef double ComplexOrRealType; #endif int main(int argc, char **argv) { if (argc < 2) return 1; typedef PsimagLite::ExpressionCalculator ExpressionCalculatorType; typedef PsimagLite::PrepassData PrepassDataType; ExpressionCalculatorType::VectorStringType ve; PsimagLite::split(ve, argv[1], ":"); PrepassDataType::VectorType vr(1,0.25); PrepassDataType pd("t", vr); PsimagLite::ExpressionPrepass::prepass(ve,pd); ExpressionCalculatorType ec(ve); std::cout< #include #include "ApplicationInfo.h" void usage(const char *progName) { std::cerr<<"Usage: "< v1(n,1.0); std::vector v2(n,1.1); std::vector v3; // multiplication by scalar v3 <= v2*1.2; 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< m3; m3 = m1 + m2; std::cout< v1(n,3.0); std::vector v2; v2 <= m3 * v1; std::cout< 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 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< 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="< m4 = 1.3*m2; PsimagLite::Matrix fm4; fm4 = 1.3*fm2; std::cout<<"CHECK PASSES="< fm5; fm5 = 1.4*fm1*fm3; fm4 += fm5; // std::cout< #include #include #include #include "Io/IoSimple.h" #include "TridiagonalMatrix.h" #include "ContinuedFraction.h" #include "ContinuedFractionCollection.h" using namespace PsimagLite; typedef double RealType; typedef TridiagonalMatrix TridiagonalMatrixType; typedef ContinuedFraction ContinuedFractionType; typedef ContinuedFractionCollection ContinuedFractionCollectionType; void usage(const char *progName) { std::cerr<<"Usage: "< #include #include #include #include "Vector.h" #include "Range.h" #include "String.h" 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 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="< \$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 testMemResolv1 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; NewMake::backupMakefile(); my $fh; open($fh, ">", "Makefile") or die "Cannot open Makefile for writing: $!\n"; NewMake::main($fh, \%args, \@drivers); } PsimagLite-3.02/drivers/continuedFraction.cpp000066400000000000000000000041511414603705100213360ustar00rootroot00000000000000// 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 #include #include #include #include "Io/IoSimple.h" #include "TridiagonalMatrix.h" #include "ContinuedFraction.h" using namespace PsimagLite; typedef double RealType; typedef TridiagonalMatrix TridiagonalMatrixType; typedef ContinuedFraction ContinuedFractionType; void usage(const char *progName) { std::cerr<<"Usage: "<0 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 #include #include #include #include "Io/IoSimple.h" #include "TridiagonalMatrix.h" #include "ContinuedFraction.h" #include "ContinuedFractionCollection.h" 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: "<=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.02/drivers/dataForAkimaSpline.txt000066400000000000000000000002141414603705100214070ustar00rootroot00000000000000#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.02/drivers/fit.cpp000066400000000000000000000151351414603705100164460ustar00rootroot00000000000000#include "Vector.h" #include #include #include "Minimizer.h" #include #include "PsimagLite.h" 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 "< 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_= "< 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 "< 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="< 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.02/drivers/integrator.cpp000066400000000000000000000016661414603705100200460ustar00rootroot00000000000000#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: "< 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< internode(PsimagLite::MPI::COMM_WORLD); internode.parallelFor(0, n, [](SizeType i, SizeType){std::cout << i;}); std::cout<<"\n--------------------------\n"; system("hostname"); } PsimagLite-3.02/drivers/isBlasThreaded.cpp000066400000000000000000000053541414603705100205440ustar00rootroot00000000000000#include "Matrix.h" #include // for atoi #include "BLAS.h" #include "Random48.h" #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: "< parallel(codeSections); MyBlasWrapper myblasWrapper(m, n, k, total); parallel.loopCreate(myblasWrapper); } PsimagLite-3.02/drivers/kernelPolynomial.cpp000066400000000000000000000052011414603705100212010ustar00rootroot00000000000000// 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 #include #include #include #include "ChebyshevSerializer.h" #include "Io/IoSimple.h" void usage(const char *progName) { std::cerr<<"Usage: "<0 \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 #include #include #include #include "Io/IoSimple.h" #include "LinearPrediction.h" typedef double FieldType; typedef PsimagLite::LinearPrediction LinearPredictionType; void usage(const char *progName) { std::cerr<<"Usage: "<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 "< #include #define USE_PTHREADS_OR_NOT_NG #include "Parallelizer.h" #include "LoadBalancerWeights.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< ParallelizerType; ParallelizerType threadObject(ConcurrencyType::codeSectionParams); HelperType helper(ntasks, nthreads); std::cout<<"Using "<", "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.02/drivers/matrix.txt000066400000000000000000000043401414603705100172210ustar00rootroot0000000000000016 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.02/drivers/minimizer.cpp000066400000000000000000000020531414603705100176620ustar00rootroot00000000000000#include "Vector.h" #include "Minimizer.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< 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 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 "< #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: "< ParallelizerType; PsimagLite::CodeSectionParams cs(nthreadsOuter); ParallelizerType threadObject(cs); HelperType helper(ntasks, nthreadsOuter, ntasksInner, nthreadsInner); std::cout<<"Using "< #include //#include int main() { std::cout<<"openblas_get_parallel= "< int main(int argc,char* argv[]) { if (argc<2) { std::cerr<<"USAGE is "<::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="< #include #include "Random48.h" 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="< #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 "< #include #include #include "Vector.h" #include "Matrix.h" #include "RungeKutta.h" #include "IoSimple.h" // 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 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: "<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::Type result; rk.solveEx(result,wbegin,wend, y0); for (SizeType i=0;i #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< 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: "< random(seed); SparseMatrixType sparse(n,n); Vector::Type seenThisColumn(n); SizeType counter = 0; for (SizeType i=0;icomputeOneState(gsEnergy, gsVector, initial, 0); std::cout<<"Energy="< 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< 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<::Type s; MatrixType vt; PsimagLite::Svd svd; svd('A', a, s, vt); std::cout<<"U\n"; std::cout< svdFallback("gesvd"); svdFallback('A', m, s, vt); std::cout<<"U\n"; std::cout< #include using namespace PsimagLite; typedef double RealType; template std::ostream& operator<<(std::ostream& os,const typename Vector::Type& v) { os<::Type& x, SizeType maxValue) { unsigned int long seed = 7334211; srand48(seed); for (SizeType i=0;i::Type& x,RealType maxValue) { unsigned int long seed = 7334211; srand48(seed); for (SizeType i=0;i 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< 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< mdense(fin); fin.close(); std::cout< m(mdense); RealType maxValue = 10.0; testMultiply(m, maxValue); std::cout< ComplexType; typedef PsimagLite::ParametersForSolver SolverParametersType; typedef PsimagLite::Vector::Type VectorComplexType; typedef PsimagLite::Vector::Type VectorRealType; if (argc!=2) { std::cout<<"USAGE: "< 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"< 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="< #include "Matrix.h" #include "GemmR.h" 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.02/drivers/testGemmR2.cpp000066400000000000000000000045171414603705100176570ustar00rootroot00000000000000#include "BLAS.h" #include "GemmR.h" #include "Random48.h" #include "Matrix.h" #include "Parallelizer2.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.02/drivers/testInput.ain000066400000000000000000000000761414603705100176460ustar00rootroot00000000000000##Ainur1.0 myscalar=3; myvector=[1,2,3,4]; mystring="Hello"; PsimagLite-3.02/drivers/testInputNg.cpp000066400000000000000000000133511414603705100201460ustar00rootroot00000000000000/* 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 "InputNg.h" #include "InputCheckBase.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 "< 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< 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.02/drivers/testIoNg.cpp000066400000000000000000000005551414603705100174200ustar00rootroot00000000000000#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<& 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.02/drivers/testIsClass.cpp000066400000000000000000000005511414603705100201210ustar00rootroot00000000000000#include "IsClass.h" #include class A {}; template int testIsClass() { return PsimagLite::IsClass::value; } int main() { std::cout<()<<"\n"; std::cout<()<<"\n"; std::cout<()<<"\n"; std::cout< >()<<"\n"; std::cout<()<<"\n"; } PsimagLite-3.02/drivers/testLanczos.cpp000066400000000000000000000016431414603705100201740ustar00rootroot00000000000000#include "LanczosSolver.h" #include "Matrix.h" #include "CrsMatrix.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="< #include "PsimagLite.h" 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,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<_" << excited << " = " << eigs[excited] <<" \n"; } std::cout<<"\n"; } PsimagLite-3.02/drivers/testLapack.cpp000066400000000000000000000017401414603705100177540ustar00rootroot00000000000000#include #include "Vector.h" #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::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="< #include #include "TestMemResolv1.h" #include typedef TestMemResolv1 TestMemResolv1Type; void recover() { std::cout<<"From disk\n"; PsimagLite::String filename = "test10.mem"; PsimagLite::MemResolv mresolv(filename,"TestMemResolv1"); std::cout<(mresolv.get()); std::cout<<"From disk: "<get(1)<<"\n"; } void save(TestMemResolv1Type* ptr) { PsimagLite::MemResolv mresolv(ptr); void* ptrCopy = mresolv.dup(); std::cout<<"copy= "<get(1)<<"\n"; mresolv.save("test10.mem","TestMemResolv1"); } int main(int argc, char *argv[]) { if (argc < 2) return 1; int n = atoi(argv[1]); if (n < 2) return 1; TestMemResolv1Type* ptr = new TestMemResolv1Type(n); TestMemResolv1Type& mytest = *ptr; mytest.setTo(10); std::cout< 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.02/drivers/testParallelizer2.cpp000066400000000000000000000011741414603705100212720ustar00rootroot00000000000000#include "Parallelizer2.h" #include "Vector.h" #include "LoadBalancerWeights.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 "< int main(int argc, char** argv) { if (argc < 3) return 1; PsimagLite::String predicate(argv[1]); PsimagLite::PredicateAwesome<>::replaceAll(predicate, "c", "5"); PsimagLite::PredicateAwesome<> pAwesome(predicate); std::cout< #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: "< ParallelizerType; ParallelizerType threadObject(ConcurrencyType::codeSectionParams); HelperType helper(ntasks, nthreads); std::cout<<"Using "< \$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.02/lib/newconfigure.pl000077500000000000000000000011541414603705100172770ustar00rootroot00000000000000#!/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.02/lib/nohdf5.psitag000066400000000000000000000001031414603705100166310ustar00rootroot00000000000000 dependency HDF5 = ( ) addto basics = CPPFLAGS += -DUSE_IO_SIMPLE PsimagLite-3.02/loki/000077500000000000000000000000001414603705100144335ustar00rootroot00000000000000PsimagLite-3.02/loki/NullType.h000066400000000000000000000025411414603705100163620ustar00rootroot00000000000000//////////////////////////////////////////////////////////////////////////////// // 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.02/loki/Sequence.h000066400000000000000000000033021414603705100163520ustar00rootroot00000000000000//////////////////////////////////////////////////////////////////////////////// // 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.02/loki/TypeManip.h000066400000000000000000000234761414603705100165260ustar00rootroot00000000000000//////////////////////////////////////////////////////////////////////////////// // 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.02/loki/TypeTraits.h000066400000000000000000002677311414603705100167340ustar00rootroot00000000000000//////////////////////////////////////////////////////////////////////////////// // 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.02/loki/Typelist.h000066400000000000000000000373041414603705100164300ustar00rootroot00000000000000//////////////////////////////////////////////////////////////////////////////// // 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.02/loki/TypelistMacros.h000066400000000000000000000443711414603705100175770ustar00rootroot00000000000000//////////////////////////////////////////////////////////////////////////////// // 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.02/scripts/000077500000000000000000000000001414603705100151645ustar00rootroot00000000000000PsimagLite-3.02/scripts/Batch.pl000077500000000000000000000026351414603705100165530ustar00rootroot00000000000000#!/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.02/scripts/FunctionParsing.pm000066400000000000000000000076411414603705100206430ustar00rootroot00000000000000#!/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.02/scripts/Make.pm000077500000000000000000000146601414603705100164110ustar00rootroot00000000000000#!/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.02/scripts/NewMake.pm000077500000000000000000000112051414603705100170530ustar00rootroot00000000000000#!/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"}; 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 *.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.02/scripts/PsiScript.pl6000077500000000000000000000043241414603705100175350ustar00rootroot00000000000000#!/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.02/scripts/PsiTag.pm000066400000000000000000000170601414603705100167150ustar00rootroot00000000000000#!/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.02/scripts/colorOutput.pl000066400000000000000000000021071414603705100200600ustar00rootroot00000000000000use 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.02/scripts/countLines.pl000066400000000000000000000016311414603705100176450ustar00rootroot00000000000000#!/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.02/scripts/doc.pl000077500000000000000000000217621414603705100163010ustar00rootroot00000000000000#!/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.02/scripts/functionSigIndent.pl000066400000000000000000000147121414603705100211600ustar00rootroot00000000000000#!/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.02/scripts/indentStrict.pl000066400000000000000000000206311414603705100201750ustar00rootroot00000000000000#!/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.02/scripts/lorentzian.pl000077500000000000000000000035271414603705100177200ustar00rootroot00000000000000#!/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.02/scripts/mpiRoundRobin.pl000077500000000000000000000015361414603705100203200ustar00rootroot00000000000000#!/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.02/scripts/naiztnerol.pl000077500000000000000000000052261414603705100177160ustar00rootroot00000000000000#!/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.02/scripts/pTeX.pl000066400000000000000000000113671414603705100164110ustar00rootroot00000000000000#!/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.02/scripts/psiTag.pl000077500000000000000000000006511414603705100167550ustar00rootroot00000000000000#!/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.02/scripts/spacesIntoTabs.pl000066400000000000000000000022231414603705100204420ustar00rootroot00000000000000#!/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.02/src/000077500000000000000000000000001414603705100142645ustar00rootroot00000000000000PsimagLite-3.02/src/Ainur/000077500000000000000000000000001414603705100153425ustar00rootroot00000000000000PsimagLite-3.02/src/Ainur/Ainur.h000066400000000000000000000002121414603705100165640ustar00rootroot00000000000000#ifndef _AINUR_H_
#define _AINUR_H_

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


#endif // _AINUR_H_
PsimagLite-3.02/src/Ainur/AinurDoubleOrFloat.h000066400000000000000000000004431414603705100212140ustar00rootroot00000000000000#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

}
#endif // AINURDOUBLEORFLOAT_H
PsimagLite-3.02/src/Ainur/AinurEmpty.h000066400000000000000000000013671414603705100176170ustar00rootroot00000000000000#ifndef _AINUR_EMPTY_H_
#define _AINUR_EMPTY_H_
#include 
#include 
#include "Vector.h"
#include "TypeToString.h"
#include "PsimagLite.h"

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();
	}

private:

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

	String dummy_;
};

}
#endif // _AINUR_EMPTY_H_
PsimagLite-3.02/src/Ainur/AinurLexical.h000066400000000000000000000024431414603705100200760ustar00rootroot00000000000000#ifndef AINURLEXICAL_H
#define AINURLEXICAL_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.02/src/Ainur/AinurReadable.h000066400000000000000000000134501414603705100202140ustar00rootroot00000000000000#ifndef AINURREADABLE_H
#define AINURREADABLE_H
#include "AinurStore.h"
#include "AinurDoubleOrFloat.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 "<
	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: "< 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.02/src/Ainur/AinurSpirit.cpp000066400000000000000000000000641414603705100203170ustar00rootroot00000000000000#ifdef USE_BOOST
#include "AinurSpirit1.cpp"
#endif
PsimagLite-3.02/src/Ainur/AinurSpirit.h000066400000000000000000000034131414603705100177650ustar00rootroot00000000000000#ifndef _AINUR_SPIRIT_H_
#define _AINUR_SPIRIT_H_
#include "../Vector.h"
#include "../TypeToString.h"
#include "../PsimagLite.h"
#include 
#include 
#include 
#include "AinurState.h"
#include "AinurLexical.h"

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;

	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);
	}

private:

	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

}
#endif // _AINUR_SPIRIT_H_
PsimagLite-3.02/src/Ainur/AinurSpirit1.cpp000066400000000000000000000073251414603705100204070ustar00rootroot00000000000000#include "AinurSpirit.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "AinurLexical.h"

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<> *(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 = +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)) return;

	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)));
	}
}

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

} // namespace PsimagLite

PsimagLite-3.02/src/Ainur/AinurState.cpp000066400000000000000000000000631414603705100201240ustar00rootroot00000000000000#ifdef USE_BOOST
#include "AinurState1.cpp"
#endif
PsimagLite-3.02/src/Ainur/AinurState.h000066400000000000000000000154761414603705100176070ustar00rootroot00000000000000#ifndef AINURSTATE_H
#define AINURSTATE_H
#include "../Vector.h"
#include 
#include "../PsimagLite.h"
#include 
#include "../Matrix.h"
#include "AinurDoubleOrFloat.h"

namespace PsimagLite {

class AinurState {

	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';
		}
	};

	template
	struct Action {

		Action(String name, std::vector& t)
		    : name_(name), t_(t)
		{}

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

	private:

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

	template
	struct ActionMatrix {

		ActionMatrix(String name, Matrix& t)
		    : name_(name), t_(t)
		{}

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

	private:

		String name_;
		Matrix& t_;
	}; // struct ActionMatrix

public:

	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);

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

		typesSpec_.push_back(d);
		values_.push_back(v);
		used_.push_back(u);
	}

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

	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 != keys_.size())
			err("printUnused: internal error\n");

		for (SizeType i = 0; i < n; ++i) {
			if (used_[i] > 0) continue;
			os<
	void readValue(SomeType& t, String label) const
	{
		int x = storageIndexByName(label);
		if (x < 0)
			err(errLabel(ERR_READ_UNDECLARED, label));
		assert(static_cast(x) < values_.size());
		String val = values_[x];
		if (isEmptyValue(val))
			err(errLabel(ERR_READ_NO_VALUE, label));

		assert(static_cast(x) < typesSpec_.size());
		convertInternal(t, val);
		used_[x]++;
	}

	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";
		}
	}

	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);
	}

private:

	int assignStorageByName(String key)
	{
		int x = storageIndexByName(key);
		if (x >= 0)
			err(errLabel(ERR_PARSE_DECLARED, key));
		keys_.push_back(key);
		return keys_.size() - 1;
	}

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

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

	template
	void convertInternal(Matrix& t,
	                     String value) const;

	template
	void convertInternal(T& t,
	                     String label,
	                     typename EnableIf::isIntegral,
	                     int>::Type = 0) const
	{
		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 convertInternal(T& t,
	                     String label,
	                     typename EnableIf::isFloat,
	                     int>::Type = 0) const
	{
		try {
			t = PsimagLite::atof(label.c_str());
		} catch (...) {
			err("FATAL: AinurState: Label " + label + " must be a real number\n");
		}
	}

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

		t = label;
	}

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

	static String ZERO_CHAR_STRING_;
	VectorStringType typesSpec_;
	VectorStringType keys_;
	VectorStringType values_;
	mutable VectorSizeType used_;
};

}
#endif // AINURSTATE_H
PsimagLite-3.02/src/Ainur/AinurState1.cpp000066400000000000000000000155231414603705100202140ustar00rootroot00000000000000#include "AinurState.h"
#include 
#include 
#include 
#include 
#include "AinurDoubleOrFloat.h"

namespace PsimagLite {

struct MyProxyFor {

	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;
		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 = atof(buffer.c_str());
				buffer = "";
				continue;
			}

			buffer += str[i];
		}

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

};

//---------

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;
}

//---------

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

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

	//if (values_[x] != "")
	//	std::cerr<<"Overwriting label "<
template 
void AinurState::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)
			MyProxyFor::convert(t_(i, j), attr[i][j]);
	}
}

//---------

template 
template 
void AinurState::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");
		MyProxyFor::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 "<
void AinurState::convertInternal(Matrix& t,
                                 String value) const
{
	namespace qi = boost::spirit::qi;
	typedef std::string::iterator IteratorType;
	typedef std::vector VectorStringType;
	typedef std::vector VectorVectorVectorType;

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

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

	ActionMatrix actionMatrix("matrix", t);
	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 AinurState::convertInternal(std::vector& t,
                                 String value,
                                 typename EnableIf::isArith ||
                                 IsComplexNumber::True ||
                                 TypesEqual::True,
                                 int>::Type) const
{
	namespace qi = boost::spirit::qi;
	typedef std::string::iterator IteratorType;
	typedef std::vector VectorStringType;

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

	Action actionRows("rows", t);

	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 AinurState::convertInternal(Matrix&,String) const;

template void AinurState::convertInternal(Matrix >&,
String) const;

template void AinurState::convertInternal(Matrix&, String) const;

template void AinurState::convertInternal(std::vector&, String, int) const;

template void AinurState::convertInternal(std::vector >&,
String,
int) const;

template void AinurState::convertInternal(std::vector&, String, int) const;

template void AinurState::convertInternal(std::vector&, String, int) const;

template void AinurState::convertInternal(std::vector&, String, int) const;
} // namespace PsimagLite
PsimagLite-3.02/src/Ainur/AinurStatements.h000066400000000000000000000156641414603705100206550ustar00rootroot00000000000000#ifndef AINURSTATEMENT_H
#define AINURSTATEMENT_H
#include "AinurStore.h"
#include "AinurReadable.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.02/src/Ainur/AinurStore.h000066400000000000000000000107641414603705100176160ustar00rootroot00000000000000#ifndef AINURSTORE_H
#define AINURSTORE_H
#include "Vector.h"
#include "AinurLexical.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= "<= 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_;
};
}
#endif // AINURSTORE_H
PsimagLite-3.02/src/Ainur/Config.make.sample000066400000000000000000000031311414603705100206640ustar00rootroot00000000000000# 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.02/src/Ainur/configure.pl000077500000000000000000000035361414603705100176720ustar00rootroot00000000000000#!/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.02/src/Ainur/input0.ain000066400000000000000000000007251414603705100172560ustar00rootroot00000000000000##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;
PsimagLite-3.02/src/Ainur/input1.ain000066400000000000000000000002771414603705100172610ustar00rootroot00000000000000##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.02/src/Ainur/prelude.ain000066400000000000000000000013121414603705100174700ustar00rootroot00000000000000integer 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.02/src/Ainur/test.cpp000066400000000000000000000017631414603705100170340ustar00rootroot00000000000000#include "Ainur.h"
#include 
#include 

void partiallyReadSomething(const PsimagLite::Ainur& ainur)
{
	SizeType n = 0;
	ainur.readValue(n, "TotalNumberOfSites");
	std::cout<<"Read: TotalNumberOfSites="< > v;
	//std::vector v;
	ainur.readValue(v, "myv");
	std::cout< > v2(10);
	ainur.readValue(v2, "myv2");
	std::cout<(fin)),
		           std::istreambuf_iterator());
		fin.close();

		str += str2;
	}


	PsimagLite::Ainur ainur(str);
	// ainur.printAll(std::cout);
	partiallyReadSomething(ainur);

}
PsimagLite-3.02/src/Ainur/testReal.cpp000066400000000000000000000017211414603705100176320ustar00rootroot00000000000000#include "Ainur.h"
#include 
#include "Matrix.h"

void partiallyReadSomething(const PsimagLite::Ainur& ainur)
{
	SizeType n = 0;
	ainur.readValue(n, "TotalNumberOfSites");
	std::cout<<"Read: TotalNumberOfSites="< v2; //(10);
	ainur.readValue(v2, "myv2");
	std::cout< mat;
	ainur.readValue(mat,"mymatrix");
	std::cout<(fin)),
		           std::istreambuf_iterator());
		fin.close();

		str += str2;
	}


	PsimagLite::Ainur ainur(str);
	// ainur.printAll(std::cout);
	partiallyReadSomething(ainur);

}
PsimagLite-3.02/src/AkimaSpline.h000066400000000000000000000053331414603705100166360ustar00rootroot00000000000000#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;iinterval_.second)
			throw RuntimeError("Akima: out of range\n");
		for (SizeType i=0;i=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::Type akimaStruct_;
	IntervalType interval_;
};

#endif //AKIMA_H_

PsimagLite-3.02/src/AllocatorCpu.h000066400000000000000000000075701414603705100170360ustar00rootroot00000000000000/*
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 
#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::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.02/src/AlmostEqual.h000066400000000000000000000070351414603705100166710ustar00rootroot00000000000000// 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 "Vector.h"
#include "MersenneTwister.h"
#include 
#include 
#include "BitManip.h"
#include 
#include 
#include "Io/IoSerializerStub.h"

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 "<

/** \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) {
		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.02/src/BitManip.h000066400000000000000000000022631414603705100161430ustar00rootroot00000000000000#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.02/src/CMakeLists.txt000066400000000000000000000004701414603705100170250ustar00rootroot00000000000000cmake_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.02/src/CanonicalExpression.h000066400000000000000000000061651414603705100204140ustar00rootroot00000000000000#ifndef PSI_CANONICAL_EXPRESSION_H
#define PSI_CANONICAL_EXPRESSION_H
#include "PsimagLite.h"
#include "QuasiCanonical.h"

namespace PsimagLite {

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 PsimagLite::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) {
			ResultType term = resultEmpty;
			bool isNotEmpty = procCanonicalTerm(term, quasiCanonical, i, aux);
			if (!isNotEmpty)
				continue;
			if (!ItemSpecType::metaEqual(term, result))
				err("CanonicalExpression: metas not equal\n");

			if (i == 0)
				result = term;
			else
				result += term;
		}

		return (ItemSpecType::isEmpty(result)) ? false : true;
	}

private:

	bool procCanonicalTerm(ResultType& term,
	                       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(term, factor, vecStr[i], quasiCanonical, aux);
		}

		if (ItemSpecType::isEmpty(term))
			return false;

		term *= factor;
		return true;
	}

	void procCanonicalFactor(ResultType& 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;
		}

		ResultType term = itemSpec_(termStr, aux);
		if (ItemSpecType::isEmpty(prev)) {
			prev = term;
			return;
		}

		if (!ItemSpecType::metaEqual(term, prev))
			err("CanonicalExpression: metas not equal\n");

		prev *= term;
	}

	const ItemSpecType& itemSpec_;
};
} // namespace PsimagLite
#endif // PSI_CANONICAL_EXPRESSION_H
PsimagLite-3.02/src/ChebyshevFunction.h000066400000000000000000000022741414603705100200700ustar00rootroot00000000000000
/*
// 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 
#include "TypeToString.h"

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.02/src/ChebyshevFunctionExplicit.h000066400000000000000000000030741414603705100215710ustar00rootroot00000000000000
/*
// 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.02/src/ChebyshevSerializer.h000066400000000000000000000147031414603705100204140ustar00rootroot00000000000000
/*
// 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 
#include "TypeToString.h"
#include "ProgressIndicator.h"
#include "Random48.h"
#include 
#include "ParametersForSolver.h"
#include "PlotParams.h"
#include "ChebyshevFunction.h"
#include 
#include "Io/IoSelector.h"
#include "Io/IoSimple.h"
#include 
#include "TridiagonalMatrix.h"

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 "<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 chebyshev_;
}; // class ChebyshevSerializer

template
const String ChebyshevSerializer::stringMarker_ = "#ChebyshevSerializerMarker";
} // namespace PsimagLite
/*@}*/
#endif  //CHEBYSHEV_SERIALIZER_H
PsimagLite-3.02/src/ChebyshevSolver.h000066400000000000000000000251541414603705100175570ustar00rootroot00000000000000/*
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 "ProgressIndicator.h"
#include "TridiagonalMatrix.h"
#include "Vector.h"
#include "Matrix.h"
#include "Random48.h"
#include "TypeToString.h"
#include "ChebyshevSerializer.h"
#include "LanczosSolver.h"
#include "LanczosOrDavidsonBase.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="<
	//! 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="<
		        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="<
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_;
};

}
#endif // CMPLX_OR_REAL_H
PsimagLite-3.02/src/CodeSectionParams.h000066400000000000000000000011611414603705100177770ustar00rootroot00000000000000#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;
};
}
#endif // CODESECTION_PARAMS_H

PsimagLite-3.02/src/Complex.h000066400000000000000000000046321414603705100160510ustar00rootroot00000000000000/*
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 
#include "../loki/TypeTraits.h"
#include "AllocatorCpu.h"

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::isFloat,T>::Type
norm(T t)
{
	return 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.02/src/Concurrency.cpp000066400000000000000000000003131414603705100172570ustar00rootroot00000000000000#include "Concurrency.h"

namespace PsimagLite {

SizeType Concurrency::mode = 0;
LabelDisabled Concurrency::mpiDisabled_;
CodeSectionParams Concurrency::codeSectionParams(1);
} // namespace PsimagLite

PsimagLite-3.02/src/Concurrency.h000066400000000000000000000166501414603705100167370ustar00rootroot00000000000000/*
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 
#include 
#include 
#include 
#include "Vector.h"
#include "Mpi.h"
#include "LabelDisabled.h"
#include "FloatingPoint.h"
#include "LAPACK.h"
#include "CodeSectionParams.h"

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="<
#include "Complex.h"
#include "TypeToString.h"
#include "ProgressIndicator.h"
#include "Random48.h"
#include "PlotParams.h"
#include "ParametersForSolver.h"
#include "Io/IoSimple.h"
#include "FreqEnum.h"
#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 "< 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 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 weight_;
	int isign_;
	typename Vector::Type eigs_;
	typename Vector::Type intensity_;
}; // class ContinuedFraction
} // namespace PsimagLite
/*@}*/
#endif  //CONTINUED_FRACTION_H

PsimagLite-3.02/src/ContinuedFractionCollection.h000066400000000000000000000073761414603705100221040ustar00rootroot00000000000000
/*
// 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 
#include "TypeToString.h"
#include "ProgressIndicator.h"
#include "FreqEnum.h"

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
	void write(IoOutputType& io) const
	{
		io.write(data_.size(), "#CONTINUEDFRACTIONCOLLECTION");
		for (SizeType i=0;i::Type data_;
}; // class ContinuedFractionCollection
} // namespace PsimagLite
/*@}*/
#endif  //CONTINUED_FRACTION_COLL_H

PsimagLite-3.02/src/CrsMatrix.h000066400000000000000000001214451414603705100163600ustar00rootroot00000000000000/*
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 
#include "BLAS.h"
#include "Matrix.h"
#include "Complex.h"
#include 
#include "loki/TypeTraits.h"
#include "Mpi.h"
#include "Io/IoSerializerStub.h"
#include 
#include "Sort.h"

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::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& c)
	{
		CrsMatrix& x = *this;
		const CrsMatrix& y = c.r1;
		const CrsMatrix& z = c.r2;
		multiply(x,y,z);
	}

	CrsMatrix(const std::ClosureOperator& 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& 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::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+1rowptr_.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 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
	typename EnableIf::isArith || IsComplexNumber::True,
	CrsMatrix>::Type
	operator=(const std::ClosureOperator& c)
	{
		*this = c.r2;
		this->values_ *= c.r1;
		return *this;
	}

	template
	typename EnableIf::isArith || IsComplexNumber::True,
	CrsMatrix>::Type
	operator+=(const std::ClosureOperator& 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,
	           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::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<
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_[i];

	SizeType nonzero;
	is>>nonzero;
	m.colind_.resize(nonzero);
	for (SizeType i=0;i>m.colind_[i];

	is>>nonzero;
	m.values_.resize(nonzero);
	for (SizeType i=0;i>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::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::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<<"--------->   "<
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
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;ieps) {
				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
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.02/src/DavidsonSolver.h000066400000000000000000000126071414603705100174050ustar00rootroot00000000000000/*
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 "LanczosVectors.h"
#include "ProgressIndicator.h"
#include "TridiagonalMatrix.h"
#include 
#include "Vector.h"
#include "Matrix.h"
#include "Random48.h"
#include "LanczosOrDavidsonBase.h"

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="<::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;ik) return;
		for (SizeType i=0;i& 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.02/src/DeepCopyOrNot.h000066400000000000000000000014761414603705100171370ustar00rootroot00000000000000#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_;
};
}
#endif // DEEPCOPYORNOT_H
PsimagLite-3.02/src/ExpressionCalculator.h000066400000000000000000000145041414603705100206120ustar00rootroot00000000000000#ifndef PSI_EXPRESSIONCALCULATOR_H
#define PSI_EXPRESSIONCALCULATOR_H

#include 
#include 
#include "Vector.h"
#include "PsimagLite.h"
#include "TypeToString.h"
#include "Stack.h"
#include "../loki/TypeTraits.h"
#include 

namespace PsimagLite {

template
struct PrepassData {
	typedef typename PsimagLite::Vector::Type VectorType;

	PrepassData() {}

	PrepassData(String names_, const VectorType& values_)
	    : names(names_), values(values_)
	{}

	String names;
	VectorType values;
};

template
class ExpressionPrepass {

	typedef PsimagLite::Vector::Type VectorStringType;

public:

	static void prepass(VectorStringType& vs,
	                    const PrepassDataType& pd)
	{
		for (SizeType i = 0; i < vs.size(); ++i) {
			int ri = getReplacementIndex(vs[i],pd);
			if (ri < 0) continue;
			vs[i] = ttos(pd.values[ri]);
		}
	}

private:

	static int getReplacementIndex(PsimagLite::String str,
	                               const PrepassDataType& pd)
	{
		SizeType l = str.size();
		if (l < 2) return -1;
		if (str[0] != '%') return -1;
		unsigned char letter = str[1];
		for (SizeType i = 0; i < pd.names.size(); ++i)
			if (pd.names[i] == letter) return i;
		return -1;
	}
}; // class ExpressionPrepass

template
class ExpressionCalculator {

	typedef PsimagLite::Vector::Type VectorSizeType;
	typedef typename PsimagLite::Vector::Type VectorType;

	enum NodeTypeEnum {NODE_NUMBER, NODE_OPERATOR};

	static const bool debug_ = false;

	struct Node {

		Node(PsimagLite::String str,SizeType ind)
		    : type(NODE_OPERATOR),index(ind),ary(0),value(0.0)
		{
			for (SizeType i = 0; i < 4; ++i) op[i] = '\0';
			SizeType l = str.size();
			if (l == 0) return;
			IsAnumberPossiblyComplex isAnumberPossiblyComplex(str);
			if (isAnumberPossiblyComplex()) {
				type = NODE_NUMBER;
				value = isAnumberPossiblyComplex.value();
			} else {
				ary = findAry(str);
				for (SizeType i = 0; i < 4; ++i)
					op[i] = (i < l) ? str[i] : '\0';
			}
		}

		void print(std::ostream& os) const
		{
			if (type == NODE_NUMBER) {
				os<::Type VectorNodeType;

public:

	typedef PsimagLite::Vector::Type VectorStringType;

	ExpressionCalculator(const VectorStringType& ve)
	    : ve_(ve), value_(0.0)
	{
		VectorNodeType vne(ve.size(),NodeType("",0));
		fillNodes(vne,ve);
		while (!onePass(vne)) {};
	}

	bool onePass(VectorNodeType& vne)
	{
		typename Stack::Type ops;
		SizeType numbers = 0;
		VectorSizeType indices(3,0);
		SizeType simplifications = 0;
		for (SizeType i = 0; i < vne.size(); ++i) {
			if (vne[i].type == NODE_NUMBER) {
				if (ops.size() == 0) {
					value_ = vne[i].value;
					return true;
				} else {
					indices[numbers] = i;
					numbers++;
					if (ops.top().ary == numbers) {
						simplify(vne,ops.top(),indices);
						numbers = 0;
						ops.pop();
						simplifications++;
					}
				}
			} else {
				if (vne[i].op[0] == '\0') continue;
				ops.push(vne[i]);
				numbers = 0;
			}
		}

		if (debug_) print(vne,"vne");
		if (simplifications > 0) return false;

		String msg("ExpressionCalculator: Syntax error in expression ");
		for (SizeType i = 0; i < ve_.size(); ++i)
			msg += ve_[i] + " ";

		throw PsimagLite::RuntimeError(msg + "\n");
	}

	const ComplexOrRealType& operator()() const
	{
		return value_;
	}

private:

	void print(const VectorNodeType& vn, PsimagLite::String label) const
	{
		std::cout<(PsimagLite::real(values[0])) %
		        static_cast(PsimagLite::real(values[1])));
		if (op[0] == 'c') return cos(values[0]);
		if (op[0] == 's') return sin(values[0]);
		if (op[0] == '?') return (PsimagLite::real(values[0]) > 0) ? values[1] : values[2];
		if (op[0] == 'e') return (op[1] == 'i') ? eToTheI(values[0]) : myExponential(values[0]);
		if (op[0] == 'l') return log(values[0]);
		return 0.0;
	}

	template
	static typename EnableIf::isArith,
	T>::Type myExponential(T v)
	{
		return ::exp(v);
	}

	template
	static typename EnableIf::True,
	T>::Type myExponential(T v)
	{
		typename Real::Type c = PsimagLite::imag(v);
		return ::exp(PsimagLite::real(v))*T(cos(c),sin(c));
	}

	template
	static typename EnableIf::isArith,
	T>::Type eToTheI(T x)
	{
		throw RuntimeError("eToTheI(" + ttos(x) + "): not unless T is complex\n");
	}

	template
	static typename EnableIf::True,
	T>::Type eToTheI(T x)
	{
		typename Real::Type r = PsimagLite::real(x);
		return ::exp(PsimagLite::imag(-x))*T(cos(r),sin(r));
	}

	static SizeType findAry(PsimagLite::String op)
	{
		if (op == "+" || op == "-" || op == "*" || op == "%") return 2;
		if (op == "c" || op == "s" || op == "e" || op == "l" || op == "ei")
			return 1;
		if (op == "?") return 3;
		return 0;
	}

	VectorStringType ve_;
	ComplexOrRealType value_;
}; // class ExpressionCalculator

} // namespace PsimagLite
#endif // PSI_EXPRESSIONCALCULATOR_H

PsimagLite-3.02/src/Fermi.h000066400000000000000000000065241414603705100155060ustar00rootroot00000000000000/*
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.02/src/FloatingPoint.h000066400000000000000000000057231414603705100172210ustar00rootroot00000000000000/*
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.02/src/FreqEnum.h000066400000000000000000000002001414603705100161470ustar00rootroot00000000000000#ifndef PSI_FREQ_ENUM_H
#define PSI_FREQ_ENUM_H

namespace PsimagLite {

enum FreqEnum {FREQ_REAL, FREQ_MATSUBARA};

}

#endif

PsimagLite-3.02/src/GemmR.h000066400000000000000000000122321414603705100154440ustar00rootroot00000000000000#ifndef PSI_GEMMR_H
#define PSI_GEMMR_H
#include "Vector.h"
#include 
#include "BLAS.h"
#include "Parallelizer2.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

}

#endif
PsimagLite-3.02/src/Geometry/000077500000000000000000000000001414603705100160575ustar00rootroot00000000000000PsimagLite-3.02/src/Geometry/Geometry.h000066400000000000000000000244761414603705100200400ustar00rootroot00000000000000/*
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 "GeometryTerm.h"
#include "GeometryEx.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;ilabel(); }

	typename ProgramGlobalsType::ConnectionEnum connectionKind(SizeType smax,
	                                                           SizeType ind,
	                                                           SizeType jnd) const
	{
		SizeType middle = smax + 1;
		if (ind=middle) return ProgramGlobalsType::ConnectionEnum::SYSTEM_ENVIRON;
		if (jnd=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);
	}

	template
	typename EnableIf::True || Loki::TypeTraits::isStdFloat,
	T>::Type vModifier(SizeType term, T value, RealType time) const
	{
		return terms_[term]->vModifier(value,time);
	}

	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_/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::Type tmpV(sitesPerBlock);
			for (SizeType j=0;j::Type tmpV(sitesPerBlock);
			typename Vector::Type tmpV2(sitesPerBlock);
			for (SizeType j=0;jmaxConnections();
	}

	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;iprint(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="<
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 = (i1i2) ? 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.02/src/Geometry/GeometryDca.h000066400000000000000000000034061414603705100204360ustar00rootroot00000000000000/*
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 "Vector.h"
#include "Io/IoNg.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.02/src/Geometry/GeometryDirection.h000066400000000000000000000172601414603705100216720ustar00rootroot00000000000000/*
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 
#include "Io/IoSerializerStub.h"
#include "Matrix.h"

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 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="< 1 || gd.aux_.idof == SPECIFIC);

		if (!isMatrix) {
			os<<"#GeometryNumbersSize="<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.02/src/Geometry/GeometryEx.h000066400000000000000000000070621414603705100203250ustar00rootroot00000000000000#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_;
};

}

#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.02/src/Geometry/GeometryTerm.h000066400000000000000000000342521414603705100206610ustar00rootroot00000000000000/*
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 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 "GeometryDirection.h"
#include "GeometryBase.h"
#include 
#include "Ladder.h"
#include "LadderX.h"
#include "LadderBath.h"
#include "KTwoNiFFour.h"
#include "Star.h"
#include "LongChain.h"
#include "LongRange.h"
#include "Honeycomb.h"
#include "ExpressionCalculator.h"
#include "PsimagLite.h"

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 "<dirs() : 0;
		for (SizeType i = 0; i < ndirs; ++i) {
			typename GeometryDirectionType::Auxiliary aux(constantValues, i, idof, orbitals_);

			directions_.push_back(GeometryDirectionType(io, aux, geometryBase_));
		}

		try {
			io.readline(vModifier_,  "GeometryValueModifier=");
		} catch (std::exception&) {}

		cacheValues();

		io.prefix() = savedPrefix;

		if (aux.debug) {
			std::cerr<<"Cached values:\n";
			std::cerr<write(label + "/geometryBase_", ioSerializer);
		ioSerializer.write(label + "/gOptions_", gOptions_);
		ioSerializer.write(label + "/vModifier_", vModifier_);
		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);
	}

	template
	typename EnableIf::True || Loki::TypeTraits::isStdFloat,
	T>::Type vModifier(T value, RealType time) const
	{
		if (vModifier_ == "") return value;

		typedef ExpressionCalculator ExpressionCalculatorType;
		typename ExpressionCalculatorType::VectorStringType ve;
		split(ve, vModifier_, ",");

		PrepassData pd;
		typename PrepassData::VectorType vr(2,0);
		vr[0] = time;
		vr[1] = value;
		pd.names = "tv";
		pd.values = vr;

		ExpressionPrepass >::prepass(ve,pd);

		ExpressionCalculatorType ec(ve);
		return ec();
	}

	//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 (i2getSubstituteSite(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;ihandle(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="<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;edof1index(i1,edof1,orbitals_);
					if (k1<0) continue;
					for (SizeType edof2=0;edof2index(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::Type directions_;
	Matrix cachedValues_;
}; // class GeometryTerm
} // namespace PsimagLite

/*@}*/
#endif // GEOMETRY_TERM_H

PsimagLite-3.02/src/Geometry/Honeycomb.h000066400000000000000000000200211414603705100201460ustar00rootroot00000000000000/*
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 
#include "GeometryBase.h"
#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.02/src/Geometry/HowToConstructANewGeometry.txt000066400000000000000000000130031414603705100240510ustar00rootroot00000000000000HOW 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.02/src/Geometry/KTwoNiFFour.h000066400000000000000000000224401414603705100203470ustar00rootroot00000000000000/*
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 
#include 
#include "GeometryBase.h"

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="<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;i0) 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.02/src/Geometry/Ladder.h000066400000000000000000000164141414603705100174310ustar00rootroot00000000000000/*
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="<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=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=l) c-=l;
		return c;
	}

	SizeType linSize_;
	SizeType leg_;
	bool isPeriodicX_;
	bool isPeriodicY_;
}; // class Ladder
} // namespace PsimagLite

/*@}*/
#endif // LADDER_H

PsimagLite-3.02/src/Geometry/LadderBath.h000066400000000000000000000202271414603705100202250ustar00rootroot00000000000000/*
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 && iconnected(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.02/src/Geometry/LadderX.h000066400000000000000000000132771414603705100175650ustar00rootroot00000000000000/*
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 
#include "Ladder.h"

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=smax-1);
		bool b = (i>smax && i<=emin+1);
		if (smax & 1) return (a || b);
		a = (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
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 (ii2) ? 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.02/src/Geometry/LongRange.h000066400000000000000000000137221414603705100201110ustar00rootroot00000000000000/*
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");
		}

		if (matrix_.rows() != matrix_.cols())
			std::cerr<<"WARNING: (LongRange) Connectors matrix isn't square\n";

		if (matrix_.rows()%linSize != 0)
			throw RuntimeError("FATAL: (LongRange) Connectors matrix " +
			                   String("isn't divisible by number of sites\n"));

		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.what();
			}
		}
	}

	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= 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 = 0; j < n; ++j)
				matrix_(i, j) = (i == j) ? 0 : value;
	}

	SizeType linSize_;
	SizeType orbitals_;
	SizeType maxConnections_;
	MatrixType matrix_;
}; // class LongRange
} // namespace PsimagLite

/*@}*/
#endif // LADDER_H

PsimagLite-3.02/src/Geometry/Star.h000066400000000000000000000103471414603705100171460ustar00rootroot00000000000000/*
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

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_;
};
}
#endif // GETBRAORKET_H
PsimagLite-3.02/src/GslWrapper.h000066400000000000000000000221541414603705100165270ustar00rootroot00000000000000/*
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 
#include "Vector.h"

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: "<
#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.02/src/InputNg.h000066400000000000000000000637751414603705100160430ustar00rootroot00000000000000/*
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 
#include 
#include 
#include 
#include "Vector.h"
#include 
#include 
#include "Map.h"
#include "Matrix.h"
#include "loki/TypeTraits.h"
#include "PsiBase64.h"
#include "Ainur/Ainur.h"

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::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;i0) checkNumbers();
		}

		void saveBuffer(const String& buffer,SizeType whatchar)
		{
			String s(__FILE__);
			String adjLabel="";
			switch(state_) {
			case IN_LABEL:
				if (verbose_) std::cout<<"Read label="<=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="<
		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=*"<
		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<first<<" "<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 {

		typedef typename Map::Type::iterator MapStringIteratorType;
		typedef typename Map::Type,MyCompareType>::Type::iterator
		MapStringVectorIteratorType;

	public:

		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<
		SizeType memResolv(SomeMemResolvType&,
		                   SizeType,
		                   String = "") const
		{
			return 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(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;isecond[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;isecond[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");
		}

		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::True &&
		Loki::TypeTraits::isArith,
		typename Real::Type>::Type
		stringToComplexOrReal(const String& s) const
		{
			return static_cast::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_
		typename Map::Type 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
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.02/src/InterNode.h000066400000000000000000000003031414603705100163200ustar00rootroot00000000000000#ifndef INTER_NODE_H
#define INTER_NODE_H
#include "Vector.h"
#include "Concurrency.h"

#ifdef USE_MPI
#include "InterNodeMpi.h"
#else
#include "InterNodeSerial.h"
#endif

#endif // INTER_NODE_H
PsimagLite-3.02/src/InterNodeMpi.h000066400000000000000000000037721414603705100170030ustar00rootroot00000000000000#ifndef INTER_NODE_MPI_H
#define INTER_NODE_MPI_H
#include "Mpi.h"
#include 
#include 
#include "Vector.h"
#include 
#include 
#include "TypeToString.h"
#include "LoadBalancerMpi.h"

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_;
};
}
#endif // INTER_NODE_MPI_H
PsimagLite-3.02/src/InterNodeSerial.h000066400000000000000000000007571414603705100174750ustar00rootroot00000000000000#ifndef INTER_NODE_SERIAL_H
#define INTER_NODE_SERIAL_H
#include "Vector.h"
#include "Mpi.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"; }
};
}
#endif // INTER_NODE_SERIAL_H
PsimagLite-3.02/src/Io/000077500000000000000000000000001414603705100146335ustar00rootroot00000000000000PsimagLite-3.02/src/Io/IoNg.h000066400000000000000000000211071414603705100156410ustar00rootroot00000000000000/*
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 
#include "Vector.h"
#include "Matrix.h"
#include "Stack.h"
#include "Map.h"
#include 
#include 
#include "IoNgSerializer.h"
#include "AllocatorCpu.h"

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.02/src/Io/IoNgSerializer.h000066400000000000000000000570701414603705100177030ustar00rootroot00000000000000#ifndef IONGSERIALIZER_H
#define IONGSERIALIZER_H
#include 
#include "../Vector.h"
#include "../TypeToString.h"
#include "TypeToH5.h"
#include 
#include 
#include "../Complex.h"

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<
	           Loki::TypeTraits::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<
	          Loki::TypeTraits::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<(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< 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();

		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, ptr, dims, ndims);
		} catch (...) {
			return false;
		}

		return true;
	}

	template
	void 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 = new H5::DataSet(hdf5file_->createDataSet(name,
		                                                                typeToH5(),
		                                                                *dataspace,
		                                                                dsCreatPlist));
		dataset->write(ptr, typeToH5());
		delete dataset;
		delete dataspace;
	}

	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;
};
}
#endif // IONGSERIALIZER_H
PsimagLite-3.02/src/Io/IoSelector.h000066400000000000000000000005171414603705100170570ustar00rootroot00000000000000#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.02/src/Io/IoSerializerEmpty.h000066400000000000000000000034521414603705100204300ustar00rootroot00000000000000#ifndef IO_SERIALIZER_EMPTY_H
#define IO_SERIALIZER_EMPTY_H
#include "../Vector.h"
#include "../TypeToString.h"
#include 
#include 
#include "../Complex.h"

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");
	}
};
}
#endif // IO_SERIALIZER_EMPTY_H
PsimagLite-3.02/src/Io/IoSerializerStub.h000066400000000000000000000004731414603705100202470ustar00rootroot00000000000000#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.02/src/Io/IoSimple.h000066400000000000000000000250631414603705100165330ustar00rootroot00000000000000/*
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 
#include 
#include 
#include "Matrix.h"
#include 
#include "Map.h"
#include "Concurrency.h"
#include "Stack.h"

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_)<
		void write(const T&x,
		           const String& label,
		           typename EnableIf::True, int>::Type = 0)
		{
			(*fout_)<
		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_)<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_))<
		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>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 "<(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))
	{}
};
}
/*@}*/
#endif

PsimagLite-3.02/src/Io/TypeToH5.cpp000066400000000000000000000020121414603705100167530ustar00rootroot00000000000000#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.02/src/Io/TypeToH5.h000066400000000000000000000006211414603705100164240ustar00rootroot00000000000000#ifndef PSI_TYPETOH5_H
#define PSI_TYPETOH5_H
#include 
#include "../AllocatorCpu.h"

namespace PsimagLite {

template
typename EnableIf::value, H5::PredType>::Type typeToH5();

template
typename EnableIf::value, H5::PredType>::Type typeToH5()
{
	return H5::PredType::NATIVE_UINT8;
}
} // PsimagLite namespace
#endif // PSI_TYPETOH5_H
PsimagLite-3.02/src/IsClass.h000066400000000000000000000005741414603705100160040ustar00rootroot00000000000000#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) };

};

}

#endif

PsimagLite-3.02/src/LAPACK.h000066400000000000000000000731131414603705100153750ustar00rootroot00000000000000//-*-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.02/src/LabelDisabled.h000066400000000000000000000006361414603705100171110ustar00rootroot00000000000000#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_;
};

}
#endif // LABEL_DISABLED_H
PsimagLite-3.02/src/LanczosCore.h000066400000000000000000000223321414603705100166610ustar00rootroot00000000000000/*
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 "LanczosVectors.h"
#include "ProgressIndicator.h"
#include "TridiagonalMatrix.h"
#include 
#include "Vector.h"
#include "Matrix.h"
#include "Random48.h"
#include "ContinuedFraction.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

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="< 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="<0) msg()<<", actual eps="<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.02/src/LanczosOrDavidsonBase.h000066400000000000000000000100431414603705100206300ustar00rootroot00000000000000/*
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.02/src/LanczosSolver.h000066400000000000000000000062661414603705100172530ustar00rootroot00000000000000#ifndef PSI_LANCZOS_SOLVER_H
#define PSI_LANCZOS_SOLVER_H
#include "Vector.h"
#include "Profiling.h"
#include "LanczosCore.h"
#include "LanczosOrDavidsonBase.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="< 0) what = ttos(excited) + " excited";
		msg()<<"Found "< 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_;
};
}
#endif // PSI_LANCZOS_SOLVER_H
PsimagLite-3.02/src/LanczosVectors.h000066400000000000000000000206731414603705100174240ustar00rootroot00000000000000/*
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 "ProgressIndicator.h"
#include 
#include "Vector.h"
#include "Matrix.h"
#include "Random48.h"
#include "ContinuedFraction.h"

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 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; ioperator()(h,i))*V2[h];

			// V2 = V2 -  Vi -- gram-schmid
			for (SizeType h=0; hoperator()(h,i)*rij;
		}

		RealType ntmp = 0.0;
		for (SizeType h=0;hrows() || 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.02/src/LapackExtra.h000066400000000000000000000054401414603705100166370ustar00rootroot00000000000000// 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.02/src/Limit.h000066400000000000000000000017151414603705100155170ustar00rootroot00000000000000#ifndef PSIMAGLITE_LIMIT_H
#define PSIMAGLITE_LIMIT_H
#include 
#include 
#include "Vector.h"
#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 "<
#include "AllocatorCpu.h"

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.02/src/LinearPrediction.h000066400000000000000000000156111414603705100176740ustar00rootroot00000000000000// 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 "Matrix.h"
#include "LAPACK.h"
#include "BLAS.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 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 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=1;i--) {
				ab[i]=ab[i-1]-roots[j]*ab[i];
			}
			ab[0]= -roots[j]*ab[0];
		}
		for (SizeType j=0;j::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::Type& B, SizeType n) const
	{
		SizeType p = B.size();
		for (SizeType l=0;l::Type y_;
	SizeType p_;
	typename Vector::Type d_;
}; // class LinearPrediction
} // namespace PsimagLite 

/*@}*/	
#endif // LINEAR_PREDICTION_H

PsimagLite-3.02/src/LoadBalancerDefault.h000066400000000000000000000013751414603705100202570ustar00rootroot00000000000000#ifndef LOADBALANCERDEFAULT_H
#define LOADBALANCERDEFAULT_H
#include "Vector.h"
#include "Sort.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.02/src/LoadBalancerMpi.h000066400000000000000000000013501414603705100174110ustar00rootroot00000000000000#ifndef LOADBALANCER_MPI_H
#define LOADBALANCER_MPI_H
#include "Vector.h"
#include "Sort.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.02/src/LoadBalancerWeights.h000066400000000000000000000037721414603705100203100ustar00rootroot00000000000000#ifndef LOADBALANCERWEIGHTS_H
#define LOADBALANCERWEIGHTS_H
#include "Vector.h"
#include "Sort.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<::Type taskNumber_;
}; // class LoadBalancerWeights
} // namespace PsimagLite
#endif // LOADBALANCERWEIGHTS_H
PsimagLite-3.02/src/Map.h000066400000000000000000000027401414603705100151550ustar00rootroot00000000000000/*
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 
#include "AllocatorCpu.h"

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<first<<"]="<second<<"\n";
	}
}

} // namespace PsimagLite

/*@}*/
#endif // MAP_HEADER_H

PsimagLite-3.02/src/Matrix.cpp000066400000000000000000000115411414603705100162360ustar00rootroot00000000000000#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="<(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="< > &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="<(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="< &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="<(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="< > &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="<(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="< >& 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.02/src/Matrix.h000066400000000000000000000644371414603705100157170ustar00rootroot00000000000000/*
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 
#include "Vector.h"
#include 
#include 
#include "LapackExtra.h"
#include "LAPACK.h"
#include "Complex.h"
#include 
#include "TypeToString.h"
#include "Mpi.h"
#include "Io/IoSerializerStub.h"
#include 
#include "BLAS.h"

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_;
		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,
	       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& 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& operator*=(const T& value)
	{
		for (SizeType i=0;i
	Matrix& operator+=(const std::ClosureOperator& 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& 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& c)
	{
		nrow_ = c.r2.nrow_;
		ncol_ = c.r2.ncol_;
		this->data_ <= c.r1*c.r2.data_;
		return *this;
	}

	template
	Matrix& operator=(const std::ClosureOperator& 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,
	                  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,
	                  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& 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& 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,
	 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::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<
void mathematicaPrint(std::ostream& os,const Matrix& A)
{
	os<<"m:={";
	for (SizeType i=0;i
void symbolicPrint(std::ostream& os,const Matrix& A)
{
	SizeType i,j;
	os<::Type values;
	String s = "symbolicPrint: Not enough characters\n";
	SizeType maxCharacters = 25;
	for (i=0;imaxCharacters)
						throw RuntimeError(s.c_str());
					char chark = k + 65;
					os<<" "<
void printNonZero(const Matrix& m,std::ostream& os)
{
	os<<"#size="<(0)) {
				os<0) os<<"\n";
	}
	os<<"#diagonal non-zero\n";
	for (SizeType i=0;i(0)) {
			os<
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(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;ieps) {
			if (verbose) {
				std::cerr<<"A("<
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("<
bool isTheIdentity(Matrix const &a)
{

	for (SizeType i=0;i1e-6)  {
				std::cerr<<"a("<(1.0))>1e-6) return false;

	return true;
}

template
bool isZero(Matrix > const &a)
{

	for (SizeType i=0;i0) return false;
	return true;
}

template
bool isZero(const Matrix& m)
{
	for (SizeType i=0;i0) 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
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
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
void transposeConjugate(Matrix& m2,const Matrix& m)
{
	m2.resize(m.cols(),m.rows());
	for (SizeType i=0;i
void transpose(Matrix& m2,const Matrix& m)
{
	m2.resize(m.cols(),m.rows());
	for (SizeType i=0;i
Matrix transposeConjugate(const Matrix& A)
{
	Matrix ret(A.cols(),A.rows());
	for (SizeType i=0;i
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::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
T norm2(const Matrix >& m)
{
	T sum = 0;
	for (SizeType i=0;i
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(k, i)) *
				        std::complex(cos(arg), sin(arg)) *
				        A(k, j);
			}

			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::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::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.02/src/MatrixNonOwned.h000066400000000000000000000034421414603705100173540ustar00rootroot00000000000000#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_;
};
}

#endif
PsimagLite-3.02/src/MemResolv.cpp000066400000000000000000000013051414603705100167000ustar00rootroot00000000000000#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.garbage_[i]);
		os<<" "<
#include "Sort.h"
#include 
#include "IsClass.h"
#include 
#include 
#include "Map.h"

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<(oldStart)<<"\n";

		fin.read(reinterpret_cast(&refTextPtr_),sizeof(refTextPtr_));
		std::cout<<"Recovered reference text pointer "<(&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= "<(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 "<(&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 "<
	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 "<
	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::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::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::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< 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_[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.02/src/MemoryCpu.h000066400000000000000000000023151414603705100163560ustar00rootroot00000000000000/*
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 "<
#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.02/src/MersenneTwister.cpp000066400000000000000000000022311414603705100201240ustar00rootroot00000000000000#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.02/src/MersenneTwister.h000066400000000000000000000020251414603705100175720ustar00rootroot00000000000000#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.02/src/MicroArchitecture.h000066400000000000000000000024651414603705100200600ustar00rootroot00000000000000#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_;
};
}
#endif // MICROARCHITECTURE_H
PsimagLite-3.02/src/Minimizer.h000066400000000000000000000166371414603705100164150ustar00rootroot00000000000000
/*
*/

#ifndef MINIMIZER_H
#define MINIMIZER_H

#include 
#include "Vector.h"
#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;
		func.n = function_.size();
		func.params = &function_;
		gsl_multimin_fminimizer_set (gslS_, &func, x, xs);

		SizeType iter = 0;
		RealType prevValue = 0;

		for (;iter::Type v(gslS_->x->data,
				                                                          gslS_->x->data+ func.n);
				RealType thisValue = function_(v);
				RealType diff = fabs(thisValue - prevValue);
				std::cerr<<"simplex: "<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;
		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 (;itergradient, tolerance);

			if (verbose_) {
				typename Vector::Type v(gslDs_->x->data,
				                                                          gslDs_->x->data + func.n);
				RealType thisValue = function_(v);
				RealType diff = fabs(thisValue - prevValue);
				std::cerr<<"conjugateGradient: "< 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;isize<<"\n";
		for (SizeType i=0;isize;i++)
			std::cerr<(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
}

#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.02/src/Minimizer.w000066400000000000000000000073721414603705100164300ustar00rootroot00000000000000\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.02/src/Mpi.cpp000066400000000000000000000053231414603705100155200ustar00rootroot00000000000000/*
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.02/src/Mpi.h000066400000000000000000000054771414603705100151770ustar00rootroot00000000000000/*
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.02/src/MpiNo.cpp000066400000000000000000000006761414603705100160230ustar00rootroot00000000000000// 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.02/src/MpiNo.h000066400000000000000000000071231414603705100154620ustar00rootroot00000000000000/*
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 
#include 
#include "Vector.h"
#include "../loki/TypeTraits.h"

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.02/src/MpiYes.cpp000066400000000000000000000126211414603705100162000ustar00rootroot00000000000000/*
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 "<= 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="<
#include 
#include "Vector.h"
#include 
#include "../loki/TypeTraits.h"

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::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::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::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::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::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= v.size()) break;
			MPI::send(v[taskNumber],0,taskNumber);
		}
	} else {
		for (int r=0;r= v.size()) break;
				NumericType value;
				MPI::recv(value,r,taskNumber);
				v[taskNumber] = value;
			}
		}
	}
}

template
typename EnableIf::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= v.size()) break;
			v[taskNumber].send(0,taskNumber,mpiComm);
		}
	} else {
		for (int r=0;r= 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= v.size()) break;
			send(v[taskNumber],0,taskNumber,mpiComm);
		}
	} else {
		for (int r=0;r= v.size()) break;
				recv(v[taskNumber],r,taskNumber,mpiComm);
			}
		}
	}
}

template
typename EnableIf::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(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::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::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::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
typename EnableIf::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::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::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::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.02/src/NoPthreads.h000066400000000000000000000064601414603705100165120ustar00rootroot00000000000000/*
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 Dmrg
/*@}*/
#endif

PsimagLite-3.02/src/NoPthreadsNg.h000066400000000000000000000105211414603705100167700ustar00rootroot00000000000000/*
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 "LoadBalancerDefault.h"
#include "CodeSectionParams.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 Dmrg

/*@}*/
#endif
PsimagLite-3.02/src/OneOperatorSpec.h000066400000000000000000000051471414603705100175140ustar00rootroot00000000000000#ifndef ONEOPERATORSPEC_H
#define ONEOPERATORSPEC_H
#include "Vector.h"
#include "PsimagLite.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 strToNumberOfFail(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

}
#endif // ONEOPERATORSPEC_H
PsimagLite-3.02/src/Optional.h000066400000000000000000000005251414603705100162240ustar00rootroot00000000000000#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_;
};
}

#endif // PSI_OPTIONAL_H
PsimagLite-3.02/src/Options.h000066400000000000000000000104261414603705100160730ustar00rootroot00000000000000/*
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 "Vector.h"
#include 
#include 
#include 
#include 
#include "PsimagLite.h"

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::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.02/src/PackIndices.h000066400000000000000000000066061414603705100166220ustar00rootroot00000000000000/*
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
#include "Vector.h"
#include "Concurrency.h"
#include "CodeSectionParams.h"
#include "Map.h"

#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.02/src/Parallelizer2.h000066400000000000000000000004341414603705100171460ustar00rootroot00000000000000#ifndef PARALLELIZER2_H
#define PARALLELIZER2_H
#include "Vector.h"
#include "Concurrency.h"

#ifdef USE_PTHREADS
#include "Parallelizer2Pthread.h"
#else

#ifdef _OPENMP
#include "Parallelizer2OpenMP.h"
#else
#include "Parallelizer2Serial.h"
#endif

#endif

#endif // PARALLELIZER2_H
PsimagLite-3.02/src/Parallelizer2OpenMP.h000066400000000000000000000013651414603705100202310ustar00rootroot00000000000000#ifndef PARALLELIZER2OPENMP_H
#define PARALLELIZER2OPENMP_H
#include "Vector.h"
#include 
#include "CodeSectionParams.h"

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_;
};
}
#endif // PARALLELIZER2OPENMP_H
PsimagLite-3.02/src/Parallelizer2Pthread.h000066400000000000000000000114121414603705100204540ustar00rootroot00000000000000#ifndef PARALLELIZER2PTHREAD_H
#define PARALLELIZER2PTHREAD_H
#include 
#include 
#include 
#include "Vector.h"
#include 
#include 
#include "TypeToString.h"
#include "CodeSectionParams.h"
#include "LoadBalancerDefault.h"

#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 *>(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 "<,
			                     &pfs[j]);
			checkForError(ret);
		}

		for (SizeType j=0; j 
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"; }
};
}
#endif // PARALLELIZER2SERIAL_H
PsimagLite-3.02/src/ParametersForSolver.h000066400000000000000000000136661414603705100204160ustar00rootroot00000000000000/*
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 "ProgressIndicator.h"
#include "TridiagonalMatrix.h"
#include "Vector.h"
#include "Matrix.h"
#include "Random48.h"
#include "TypeToString.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.02/src/Permutations.h000066400000000000000000000115341414603705100171330ustar00rootroot00000000000000/*
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::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()) 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::Type data_;

	}; // Permutations
	
	template
	std::ostream& operator<<(std::ostream& os,
	                          const Permutations& ig)
	{
		for (SizeType i=0;i
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.02/src/PredicateAnd.h000066400000000000000000000043601414603705100167630ustar00rootroot00000000000000#ifndef PREDICATEAND_H
#define PREDICATEAND_H
#include "Vector.h"
#include "PredicateSimple.h"
#include "PsimagLite.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_;
};
}
#endif // PREDICATEAND_H
PsimagLite-3.02/src/PredicateAwesome.h000066400000000000000000000100551414603705100176570ustar00rootroot00000000000000#ifndef PREDICATE_AWESOME_H
#define PREDICATE_AWESOME_H

#include "Vector.h"
#include "PredicateAnd.h"
#include "PredicateDefaultSpec.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;
	}

	static 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'
		}
	}

private:

	String pred_;
	VectorPredicateAndType predicateAnd_;
};
}
#endif // PREDICATE_AWESOME_H
PsimagLite-3.02/src/PredicateDefaultSpec.h000066400000000000000000000003251414603705100204550ustar00rootroot00000000000000#ifndef PREDICATEDEFAULTSPEC_H
#define PREDICATEDEFAULTSPEC_H

namespace PsimagLite {

class PredicateDefaultSpec {

public:

    void operator()(PsimagLite::String) const {}
};
}
#endif // PREDICATEDEFAULTSPEC_H
PsimagLite-3.02/src/PredicateSimple.cpp000066400000000000000000000002341414603705100200410ustar00rootroot00000000000000#include "PredicateSimple.h"

namespace PsimagLite {
PredicateSimple::VectorStringType PredicateSimple::ops_ =
{"==", "!=", "<=", ">=", ">", "<", "%%"};

}
PsimagLite-3.02/src/PredicateSimple.h000066400000000000000000000101721414603705100175100ustar00rootroot00000000000000#ifndef PREDICATE_SIMPLE_H
#define PREDICATE_SIMPLE_H
#include "Vector.h"
#include "PsimagLite.h"
#include "ExpressionCalculator.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 ExpressionCalculator ExpressionCalculatorType;
		ExpressionCalculatorType expressionCalculator(tokens);
		return expressionCalculator();
	}

	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_;
};
}
#endif // PREDICATE_SIMPLE_H
PsimagLite-3.02/src/Profiling.h000066400000000000000000000035361414603705100163750ustar00rootroot00000000000000/*
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 
#include "MemoryUsage.h"
#include "PsimagLite.h"
#include "ProgressIndicator.h"

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
} // PsimagLite

#endif

PsimagLite-3.02/src/ProgressIndicator.cpp000066400000000000000000000056601414603705100204400ustar00rootroot00000000000000/*
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.02/src/ProgressIndicator.h000066400000000000000000000132621414603705100201020ustar00rootroot00000000000000/*
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 
#include 
#include 
#include "Concurrency.h"
#include "MemoryUsage.h"
#include 
#include 
#include "TypeToString.h"

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<
	void printline(const String &s,SomeOutputType& os) const
	{
		if (threadId_ != 0) return;
		if (rank_!=0) return;
		prefix(os);
		os<
	void prefix(SomeOutputStreamType& os) const
	{
		const MemoryUsage::TimeHandle t = musage_.time();
		const double seconds = t.millis();
		const SizeType prec = os.precision(3);
		prefixHelper(os)<
	SomeOutputStreamType& prefixHelper(SomeOutputStreamType& os) const
	{
		return os;
	}

	String caller_;
	SizeType threadId_;
	SizeType rank_;
}; // ProgressIndicator

} // namespace PsimagLite

/*@}*/
#endif

PsimagLite-3.02/src/PsiBase64.cpp000066400000000000000000000030021414603705100164630ustar00rootroot00000000000000/*
 *****
 ***** 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.02/src/PsiBase64.h000066400000000000000000000111301414603705100161310ustar00rootroot00000000000000/*
 *****
 ***** 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 "Vector.h"
#include "Io/IoSerializerStub.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<> 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
}

#endif // PSIBASE64_H

PsimagLite-3.02/src/PsimagLite.cpp000066400000000000000000000045501414603705100170320ustar00rootroot00000000000000#include "PsimagLite.h"

namespace PsimagLite {

std::ostream& operator<<(std::ostream& os,const std::pair& p)
{
	os<>(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());
}

const int PsiApp::libSizeOfSizeType_ = sizeof(SizeType);

} // namespace PsimagLite

void err(PsimagLite::String s)
{
	PsimagLite::err(s);
}

PsimagLite-3.02/src/PsimagLite.h000066400000000000000000000114231414603705100164740ustar00rootroot00000000000000#ifndef PSI_PSIMAGLITE_H
#define PSI_PSIMAGLITE_H

#include "MicroArchitecture.h"
#include 
#include 
#include "Concurrency.h"
#include "AnsiColors.h"
#include "TypeToString.h"
#include "Vector.h"
#include "Random48.h"
#include "PsiBase64.h"
#include 
#include 

namespace PsimagLite {

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 = " ");

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 "<::True>
class IsAnumberPossiblyComplex {};


template
class IsAnumberPossiblyComplex {
public:

	IsAnumberPossiblyComplex(String str)
	    : flag_(isAfloat(str)), value_(0)
	{
		if (flag_) value_ = PsimagLite::atof(str.c_str());
	}

	bool operator()() const { return flag_; }

	ComplexOrRealType value() const { return value_; }

private:

	bool flag_;
	ComplexOrRealType value_;
};

template
class IsAnumberPossiblyComplex {

public:

	IsAnumberPossiblyComplex(String str)
	    : flag_(false), value_(0)
	{
		// (a, b) or (a,b)
		SizeType l = str.length();
		if (l < 5) {
			seeIfItsAfloat(str);
			return;
		}

		if (str[0] != '(') {
			seeIfItsAfloat(str);
			return;
		}

		String buffer;
		String realPart;
		String imagPart;
		for (SizeType i = 1; i < l; ++i) {
			if (str[i] == ',') {
				realPart = buffer;
				buffer = "";
			} else if (str[i] == ')') {
				imagPart = buffer;
				buffer = "";
			} else if (str[i] != ' ') {
				buffer += str[i];
			} else {
				flag_ = false;
				return;
			}
		}

		flag_ = (isAfloat(realPart) && isAfloat(imagPart));
		if (!flag_) return;
		value_ = ComplexOrRealType(PsimagLite::atof(realPart), PsimagLite::atof(imagPart));
 	}

	bool operator()() const { return flag_; }

	ComplexOrRealType value() const { return value_; }

private:

	void seeIfItsAfloat(String str)
	{
		flag_ = isAfloat(str);
		if (!flag_) return;
		value_ = PsimagLite::atof(str);
	}

	bool flag_;
	ComplexOrRealType value_;
};

} // namespace PsimagLite

void err(PsimagLite::String);

#endif // PSI_PSIMAGLITE_H

PsimagLite-3.02/src/Pthreads.h000066400000000000000000000146411414603705100162150ustar00rootroot00000000000000/*
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 
#include 
#include "AllocatorCpu.h"
#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[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 ,
			                     &pfs[j]);
			checkForError(ret);
		}

		for (SizeType j=0; j 
#include 
#include "Mpi.h"
#include "Pthreads.h"

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 Dmrg

/*@}*/
#endif

PsimagLite-3.02/src/PthreadsNg.h000066400000000000000000000230121414603705100164720ustar00rootroot00000000000000/*
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 
#include 
#include 
#include "Vector.h"
#include "LoadBalancerDefault.h"
#include 
#include 
#include "TypeToString.h"
#include "CodeSectionParams.h"

#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  0) ? pthread_attr_setstacksize(attr[j], stackSize_) : 0;
			if (ret != 0) {
				std::cerr<<__FILE__;
				std::cerr<<"\tpthread_attr_setstacksize() has returned non-zero "<,
			                     &pfs[j]);
			checkForError(ret);
		}

		for (SizeType j=0; j 
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] = strToRealOrImag(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 = PsimagLite::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:

	static ComplexOrRealType pureRealOrPureImag(String t)
	{
		static const bool isComplex = IsComplexNumber::True;
		CpmlxOrReal cmplxOrReal(t);
		return cmplxOrReal.value();
	}

	static ComplexOrRealType strToRealOrImag(String content)
	{
		VectorStringType terms;
		split(terms, content, "+");
		ComplexOrRealType sum = 0;
		const SizeType n = terms.size();
		for (SizeType i = 0; i < n; ++i) {
			sum += pureRealOrPureImag(terms[i]);
		}

		return sum;
	}

	String str_;
	String mainBuffer_;
	VectorStringType ats_;
	VectorStringType terms_;
	VectorType cachedValues_;
};
}
#endif // QUASICANONICAL_H
PsimagLite-3.02/src/Random48.h000066400000000000000000000025411414603705100160330ustar00rootroot00000000000000/*
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 
#include 
#include "Vector.h"

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(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.02/src/RandomForTests.h000066400000000000000000000024421414603705100173510ustar00rootroot00000000000000/*
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.02/src/RootFindingBisection.h000066400000000000000000000037661414603705100205330ustar00rootroot00000000000000
/** \ingroup PsimagLite */
/*@{*/

/*! \file RootFindingBisection.h
 *
 *  RootFindingBisection such as chemical potential
 *
 */
#ifndef ROOT_FIND_BISECT_H
#define ROOT_FIND_BISECT_H
#include "ProgressIndicator.h"
#include "Matrix.h"
#include "Fermi.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=0) ?  1  : -1;
	}

	const FunctionType& function_;
	SizeType maxIter_;
	RealType tolerance_;
	RealType a_,b_;
}; // RootFindingBisection
} // namespace PsimagLite

/*@}*/
#endif// ROOT_FIND_BISECT_H

PsimagLite-3.02/src/RungeKutta.h000066400000000000000000000121751414603705100165340ustar00rootroot00000000000000/*
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 
#include "Complex.h"
#include "Vector.h"
#include "Matrix.h"

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& 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<
#include 
#include 
#include  // <-- just for drand48 and srand48(seed)
#include 
#include "Sort.h"
#include "loki/TypeTraits.h"

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
	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<
	typename EnableIf::True, void>::Type
	saveVector(SomeIoOutputType& io,const SomeVectorType& v) const
	{
		io<
	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[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::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 Dmrg
#endif

PsimagLite-3.02/src/SampleCRSMatrix.w000066400000000000000000000150751414603705100174420ustar00rootroot00000000000000\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.02/src/Sort.h000066400000000000000000000023611414603705100153660ustar00rootroot00000000000000// sort algorithm example
#ifndef SORT_H_H
#define SORT_H_H
#include 
#include 
#include "Vector.h"
#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

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 s;
			ColumnsType iperm(cols_.size());
			s.sort(cols_,iperm);
			SizeType prevCol = cols_[0];
			SizeType counter = 0;
			ValueType value = 0;
			for (SizeType i=0;i

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 s;
			ColumnsType iperm(counter_);
			s.sort(cols_,iperm,counter_);
			SizeType prevCol = cols_[0];
			SizeType counter = 0;
			ValueType value = 0;
			for (SizeType i=0;i::Type values_;
		SizeType counter_;
			
	}; // class SparseRowCached

} // namespace Dmrg 

/*@}*/
#endif // SPARSE_ROW_CACHED_H
PsimagLite-3.02/src/SparseVector.h000066400000000000000000000236611414603705100170650ustar00rootroot00000000000000/*
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 
#include 
#include 
#include 
#include "Vector.h" // in PsimagLite
#include "Sort.h"

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::Type& v,SizeType offset,SizeType total)
			{
				resize(total);
				for (SizeType i=0;i::Type& dest,SizeType i0, SizeType total, bool test=false) const
			{
				if (test) {
					PairType firstLast = findFirstLast();
					if (i0>firstLast.first || i0+total
			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
			SizeType findPartition(const SomeBasisType& parts) const
			{
				PairType firstLast = findFirstLast();
				SizeType ret = 0;
				for (SizeType i=0;i=parts.partition(i)) {
						ret = i;
					} else {
						break;
					}
				}
				SizeType ret2 = 1;
				for (SizeType i=0;iparts.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 operator-=(const SparseVector& v)
			{
				 for (SizeType i=0;i& v) const
			{
				assert(isSorted_);
				assert(v.isSorted_);
				for (SizeType i=0;i& 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 (;iindex) 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;i1) 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::Type indices;

				for (SizeType i=1;i1e-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
	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
	inline FieldType norm(const SparseVector >& v)
	{
		std::complex sum=0;
		for (SizeType i=0;i 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;
}

}

PsimagLite-3.02/src/SpecialFunctions.h000066400000000000000000000003671414603705100177140ustar00rootroot00000000000000#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);

}
#endif // PSI_SPECIAL_FUNCTIONS_H

PsimagLite-3.02/src/Stack.h000066400000000000000000000075461414603705100155160ustar00rootroot00000000000000/*
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 
#include "AllocatorCpu.h"
#include "Vector.h"

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<
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.02/src/SumDecomposition.h000066400000000000000000000032171414603705100177410ustar00rootroot00000000000000#ifndef PSI_SUM_DECOMPOSITION_H
#define PSI_SUM_DECOMPOSITION_H

#include 
#include 
#include "Vector.h"
#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<
#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 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= "<
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 = "<
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 = "<
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 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.02/src/TypeToString.h000066400000000000000000000006771414603705100170620ustar00rootroot00000000000000
/* PsimagLite */
/* See LICENSE for licensing details and disclaimers */
#ifndef TYPE_TO_STRING_H
#define TYPE_TO_STRING_H

#include 
#include "AllocatorCpu.h"

namespace PsimagLite {
template
String typeToString(T t)
{
	std::stringstream ss;
	String str;
	ss.precision(10);
	ss<>str;
	return str;
}
}

template
PsimagLite::String ttos(T t)
{
	return PsimagLite::typeToString(t);
}

#endif // TYPE_TO_STRING_H

PsimagLite-3.02/src/Vector.h000066400000000000000000000330361414603705100157040ustar00rootroot00000000000000/*
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 
#include 
#include 
#include "Complex.h"
#include "AllocatorCpu.h"
#include "../loki/TypeTraits.h"

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
vector operator*(const vector,AA>& v1,
                       const vector& v2)
{
	vector v3(v2.size());
	for (SizeType i=0;i
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::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
typename PsimagLite::EnableIf::True && PsimagLite::IsNumber::True,
void>::Type operator<=(vector& v,
                const ClosureOperator,ClosureOperations::OP_MULT>,
                ClosureOperations::OP_MULT>& c)
{
	v = c.r2.r2;
	T2 tmp = c.r1*c.r2.r1;
	for (SizeType i=0;i
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::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
void operator<=(vector& v,
                const ClosureOperator,
                ClosureOperator, ClosureOperations::OP_MULT>,
                ClosureOperations::OP_PLUS>& c)
{
	v.resize(c.r1.size());
	for (SizeType i=0;i
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
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
void operator<=(vector& v,
                const 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
ClosureOperator,vector,ClosureOperations::OP_MINUS>
operator-(const vector& v1,const vector& v2)
{
	return ClosureOperator,vector,ClosureOperations::OP_MINUS>(v1,v2);
}

template
typename PsimagLite::EnableIf::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
void operator<=(vector& v,
                const ClosureOperator,
                ClosureOperator, ClosureOperations::OP_MULT>,
                ClosureOperations::OP_MINUS>& c)
{
	v.resize(c.r1.size());
	for (SizeType i=0;i
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
void operator<=(vector& v,
                const ClosureOperator<
                ClosureOperator,
                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
vector operator+=(vector& v,
                               const vector& w)
{
	for (SizeType i=0;i
vector operator+=(vector& v,
                       const ClosureOperator,ClosureOperations::OP_MULT>& w)
{
	for (SizeType i=0;i
vector operator-=(vector& v,const vector& w)
{
	for (SizeType i=0;i
vector operator-=(vector& v,
                       const ClosureOperator,ClosureOperations::OP_MULT>& w)
{
	for (SizeType i=0;i
vector operator*=(vector& v,
                        const T2& t2)
{
	for (SizeType i=0;i
vector operator/=(vector& v,
                        const T2& t2)
{
	for (SizeType i=0;i
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<
ostream &operator<<(ostream &s,
                    const vector,A>& v)
{
	s<
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>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
void randomizeVector(typename Vector::Type& v,
                     const X& a,
                     const X& b,
                     const RandomType& r)
{
	for (SizeType i=0;i
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
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.02/src/Version.h000066400000000000000000000001051414603705100160560ustar00rootroot00000000000000#ifndef PSIMAGLITE_VERSION
#define PSIMAGLITE_VERSION "3.02"
#endif