Katzlab dd76ab1d12 Added PTL2 Scripts
These are PTL2 files from Auden 2/9
2023-02-14 11:20:52 -05:00

375 lines
8.0 KiB
C++

#include "matrixUtils.h"
#include "errorMsg.h"
#include <cmath>
#include <string>
#include <ctype.h>
#include <cctype>
#include <cstdlib>
Vdouble getDiagonalFromMatrix(VVdouble &mat){
Vdouble diagonal;
for (int i=0; i<mat.size(); i++)
diagonal.push_back(mat[i][i]);
return diagonal;
}
Vdouble getSubDiagonalFromMatrix(VVdouble &mat){
Vdouble diagonal;
for (int i=0; i<mat.size()-1; i++)
diagonal.push_back(mat[i+1][i]);
return diagonal;
}
void readMatrixFromFile(VVdouble &mat,string fileName){
ifstream in(fileName.c_str());
if (!in){
string err="in function readMatrixFromFile, empty file or non-existant:";
err+=fileName;
errorMsg::reportError(err);
}
int i=0;
mat.resize(1);
while (!in.eof()) {
string row;
int k=0;
getline(in,row,'\n');
while (k<row.size()){
string value;
while (row[k]!=' ' && k<row.size()){
value+=row[k];
k++;
}
k++;
mat[i].push_back(atof(value.c_str()));
//j++;
//mat.resize(j);
}
if (!in.eof())
mat.resize(++i+1);
}
in.close();
}
void printMatrix(const VVdouble &mat, ostream &out) {
int num=mat.size();
for (int row=0; row<num; row++) {
for (int position=0; position<mat[row].size(); position++) {
out << mat[row][position] << '\t';
}
out << endl ;
}
out << endl ;
}
void printMatrix(const VVint &mat, ostream &out) {
int num=mat.size();
for (int row=0; row<num; row++) {
for (int position=0; position<mat[row].size(); position++) {
out << mat[row][position] << '\t';
}
out << endl ;
}
out << endl ;
out<<"---------------------------------------------"<<endl;
}
VVdouble transpose(const VVdouble &mat){
VVdouble matT;
int n=mat.size();
resizeMatrix(matT,n,n);
for (int i=0; i<n;i++){
for (int j=0; j<n;j++) {
matT[i][j]=mat[j][i];
}
}
return matT;
}
VVdouble subtract(const VVdouble &mat1,const VVdouble &mat2){
VVdouble newMat=add(mat1,reverseSign(mat2));
return newMat;
}
VVdouble reverseSign(const VVdouble &mat1){
VVdouble newMat(mat1.size());
for (int i=0;i<mat1.size();i++){
newMat[i].resize(mat1[i].size());
for (int j=0;j<mat1.size();j++){
newMat[i][j]=-mat1[i][j];
}
}
return newMat;
}
void findMaxInVector(const Vdouble &vec, MDOUBLE &maxValue, int &argmax){
MDOUBLE tempMax=VERYSMALL;
int tempArgMax=0;
for (int i=0; i<vec.size(); i++){
if (vec[i]>tempMax){ // TEST DEBUG!!! if '>' is used, the first Max is chosen, if '>' the last max
tempMax=vec[i];
tempArgMax=i;
}
}
maxValue=tempMax;
argmax=tempArgMax;
}
void findMinInVector(const Vdouble &vec, MDOUBLE &minValue, int &argmin) {
Vdouble minusCopy(vec.size());
for (int i=0; i<vec.size(); i++){
minusCopy[i] = -vec[i];
}
findMaxInVector(minusCopy, minValue, argmin);
minValue = -minValue;
}
bool isMinEQMaxInVector(const Vdouble &vec){
bool isMinEQMaxInVector = false;
MDOUBLE maxValue, minValue;
int argmax, argmin;
findMaxInVector(vec,maxValue,argmax);
findMinInVector(vec,minValue,argmin);
if(maxValue == minValue)
isMinEQMaxInVector = true;
return isMinEQMaxInVector;
}
MDOUBLE averageElementInVector(const Vdouble &vec) {
MDOUBLE sum=0.0;
for (int i=0; i<vec.size(); i++){
sum+=vec[i];
}
return sum/vec.size();
}
void appendBinaryVectors(Vint &vec1, const Vint &vec2){
for (int i=0; i < vec2.size(); i++)
if (vec2[i]==1)
vec1[i]=1;
}
void appendVectors(Vint &vec1, const Vint &vec2) {
for (int i=0; i<vec2.size();i++)
vec1.push_back(vec2[i]);
}
void appendVectors(VVdouble &vec1, const VVdouble &vec2) {
for (int i=0; i<vec2.size();i++)
for (int j=0; j<vec2[i].size();j++)
vec1[i].push_back(vec2[i][j]);
}
Vint complementBinaryVec(Vint&bufferVec) {
for (int i=0; i<bufferVec.size(); i++)
bufferVec[i]=abs(bufferVec[i]-1);
return bufferVec;
}
//reads a vertical vector of float numbers(separated by \n)
void readDoubleVecFromFile(Vdouble &vec,string fileName){
ifstream in(fileName.c_str());
if (!in){
string err="in function readDoubleVecFromFile, empty file or non-existant:";
err+=fileName;
errorMsg::reportError(err);
}
string row;
while (!in.eof()){
getline(in,row,'\n');
//if (isalnum(*(row.c_str())) || (row[0]=="."))
if (isspace(*(row.c_str())) || row=="") continue;
vec.push_back(atof(row.c_str()));
}
in.close();
}
void normalize(Vdouble &vec){
MDOUBLE sum=0.0;
MDOUBLE squareSum=0.0;
int N=vec.size();
int i=0;
for (i=0;i<N;i++) sum+=vec[i];
for (i=0;i<N;i++) squareSum+=(vec[i]*vec[i]);
MDOUBLE avg=sum/N;
MDOUBLE sqrAvg=squareSum/N;
MDOUBLE stdDev=sqrt(sqrAvg-avg*avg);
for (i=0;i<N;i++) vec[i]=(vec[i]-avg)/stdDev;
}
void scaleByAverage(Vdouble &vec){
MDOUBLE sum=0.0;
MDOUBLE squareSum=0.0;
int N=vec.size();
int i=0;
for (i=0;i<N;i++) sum+=vec[i];
for (i=0;i<N;i++) squareSum+=(vec[i]*vec[i]);
MDOUBLE avg=sum/N;
for (i=0;i<N;i++) vec[i]=(vec[i])/avg;
}
Vdouble solveLinearEquations(VVdouble A,Vdouble b){
// VVdouble Acopy=A; //creating a copy, since ludcmp&lubksb destroy the input
// Vdouble bcopy=b;
MDOUBLE d; //required for ludcmp; irrelevant for us.
Vdouble indx; //required for ludcmp; irrelevant for us.
ludcmp(A,indx,d); //decomposes A into product of diagonal matrices
lubksb(A,indx,b); //solves
return b;
}
void ludcmp(VVdouble &a, Vdouble &indx, MDOUBLE &d)
{
const MDOUBLE TINY=1.0e-20;
int i,imax=0,j,k;
MDOUBLE big,dum,sum,temp;
int n=a.size();
Vdouble vv(n);
indx.resize(n);//my addition
d=1.0;
for (i=0;i<n;i++) {
big=0.0;
for (j=0;j<n;j++)
if ((temp=fabs(a[i][j])) > big) big=temp;
if (big == 0.0) errorMsg::reportError("Singular matrix in routine ludcmp");
vv[i]=1.0/big;
}
for (j=0;j<n;j++) {
for (i=0;i<j;i++) {
sum=a[i][j];
for (k=0;k<i;k++) sum -= a[i][k]*a[k][j];
a[i][j]=sum;
}
big=0.0;
for (i=j;i<n;i++) {
sum=a[i][j];
for (k=0;k<j;k++) sum -= a[i][k]*a[k][j];
a[i][j]=sum;
if ((dum=vv[i]*fabs(sum)) >= big) {
big=dum;
imax=i;
}
}
if (j != imax) {
for (k=0;k<n;k++) {
dum=a[imax][k];
a[imax][k]=a[j][k];
a[j][k]=dum;
}
d = -d;
vv[imax]=vv[j];
}
indx[j]=imax;
if (a[j][j] == 0.0) a[j][j]=TINY;
if (j != n-1) {
dum=1.0/(a[j][j]);
for (i=j+1;i<n;i++) a[i][j] *= dum;
}
}
}
void lubksb(VVdouble &a, Vdouble &indx, Vdouble &b)
{
int i,ii=0,ip,j;
MDOUBLE sum;
int n=a.size();
for (i=0;i<n;i++) {
ip=(int)(indx[i]);
sum=b[ip];
b[ip]=b[i];
if (ii != 0)
for (j=ii-1;j<i;j++) sum -= a[i][j]*b[j];
else if (sum != 0.0)
ii=i+1;
b[i]=sum;
}
for (i=n-1;i>=0;i--) {
sum=b[i];
for (j=i+1;j<n;j++) sum -= a[i][j]*b[j];
b[i]=sum/a[i][i];
}
}
//get the first norm sum{abs(Mij)}
MDOUBLE getMatrixNorm(const VVdouble &mat) {
MDOUBLE res(0.0);
for (int i=0; i<mat.size(); i++){
for (int j=0; j<mat[i].size();j++){
res += fabs(mat[i][j]);
}
}
return res;
}
//get the first norm sum{abs(Mij)} from vector of Matrices
MDOUBLE getVMatrixNorm(const VVVdouble &mat) {
MDOUBLE res(0.0);
for (int i=0; i<mat.size(); i++){
for (int j=0; j<mat[i].size();j++){
for (int k=0; k<mat[i][j].size();k++){
res += fabs(mat[i][j][k]);
}
}
}
return res;
}
//get the specific coordinates sum from vector of Matrices
MDOUBLE getVMatrixJK(const VVVdouble &mat, const int j, const int k) {
MDOUBLE res(0.0);
for (int i=0; i<mat.size(); i++){
res += fabs(mat[i][j][k]);
}
return res;
}
/********************************************************************************************
*********************************************************************************************/
void resize_VVVV(int dim1, int dim2, int dim3, int dim4, VVVVdouble& vetor){
vetor.resize(dim1);
for (int posNum=0;posNum<vetor.size();++posNum){
vetor[posNum].resize(dim2);
for (int n=0;n<vetor[posNum].size();++n){
resizeMatrix(vetor[posNum][n],dim3,dim4);
}
}
}
/********************************************************************************************
*********************************************************************************************/
void resize_VVV(int dim1, int dim2, int dim3, VVVdouble& vetor){
vetor.resize(dim1);
for (int n=0;n<vetor.size();++n){
resizeMatrix(vetor[n],dim2,dim3);
}
}