public void Initialize(SOCJT nSocjt, FileInfo input, List<ModeInfo> Modes, string[] inputFile, bool isQuad, Eigenvalue[] fitFile) { nSoc = nSocjt; nInput = input; nModes = Modes; nInputFile = inputFile; nIsQuad = isQuad; nFitFile = fitFile; }
/// <summary> /// Returns the RMS deviation between two arrays of Eigenvalues including the origin value. /// </summary> /// <param name="exp"> /// Eigenvalues from the .fit file. /// </param> /// <param name="socjtOut"> /// Eigenvalues from the SOCJT routine. /// </param> /// <param name="origin"> /// Origin shift to be applied to the experimental values. /// </param> /// <returns> /// RMS error. /// </returns> public static double Comparer(Eigenvalue[] exp, Eigenvalue[] socjtOut, double origin) { double RMS = 0D; //int h = 0; for (int i = 0; i < exp.Length; i++) { for (int j = 0; j < socjtOut.Length; j++) { if (exp[i].JBlock == socjtOut[j].JBlock) { if (exp[i].Number == socjtOut[j].Number) { if (exp[i].IsA1 == socjtOut[j].IsA1) { RMS += Math.Pow((exp[i].Evalue + origin) - socjtOut[j].Evalue, 2D); //h = j; break; } } } } } return RMS; }
/// <summary> /// Returns a vector containing the error between experimental and calculated eigenvalues. /// </summary> /// <param name="exp"> /// Experimental eigenvalues. /// </param> /// <param name="socjtOut"> /// Calculated eigenvalues. /// </param> /// <param name="origin"> /// Value of the transition origin to be used. /// </param> /// <param name="raw"> /// If true, returns raw (exp - calc) eigenvalues. If false, returns (exp - calc)^2. /// </param> /// <returns> /// double[] containing error values. /// </returns> public static double[] ComparerVec(Eigenvalue[] exp, Eigenvalue[] socjtOut, double origin, bool raw) { List<double> errors = new List<double>(); double[] errorsvec; //double ZPE = socjtOut[0].Ev; for (int i = 0; i < exp.Length; i++) { for (int j = 0; j < socjtOut.Length; j++) { if (exp[i].JBlock == socjtOut[j].JBlock) { if (exp[i].Number == socjtOut[j].Number) { if (exp[i].Sigma == socjtOut[j].Sigma) { if (exp[i].IsA1 == socjtOut[j].IsA1) // Added the symmetry conditions { if (raw == false) { errors.Add(Math.Pow((exp[i].Evalue + origin) - socjtOut[j].Evalue, 2D));//took out ZPE break; } if (raw == true) { errors.Add((exp[i].Evalue + origin) - socjtOut[j].Evalue);//took out ZPE break; } } } } } } } errorsvec = errors.ToArray(); return errorsvec; }
public List<string> fit(List<ModeInfo> Modes, bool isQuad, string[] inputFile, FileInfo input, String filepath) { //string to return List<string> output = new List<string>(); //reads and parses fit file string[] fitF = {}; try { fitF = FileInfo.FileRead(filepath); } catch(FileNotFoundException) { throw new FileNotFoundException("The fit file does not exist."); } //assign number of eigenvalues to be fit from fitFile int nToFit = Convert.ToInt16(fitF[0]); //create new Eigenvalue array to store the values from the fit file for each value being fit Eigenvalue[] userInput = new Eigenvalue[nToFit]; //initialize the Eigenvalue array for the fit values from the fit file for (int i = 0; i < nToFit; i++) { if (input.useSeed) { userInput[i] = new Eigenvalue(Convert.ToDecimal(fitF[i * 5 + 2]), Convert.ToInt16(fitF[i * 5 + 3]), Convert.ToDecimal(fitF[i * 5 + 4]), Convert.ToDouble(fitF[i * 5 + 1]), FileInfo.TorF(fitF[i * 5 + 5])); } else // if the seed switch is off, all Lanczos eigenvalues will be labelled as not A1, so we will label all fit file values as not A1 { userInput[i] = new Eigenvalue(Convert.ToDecimal(fitF[i * 5 + 2]), Convert.ToInt16(fitF[i * 5 + 3]), Convert.ToDecimal(fitF[i * 5 + 4]), Convert.ToDouble(fitF[i * 5 + 1]), false); } } //initializes the X vector, boundary conditions and variable scales //xList will contain each parameter being fit List<double> xList = new List<double>(); //the lower bounds for each variable being fit, these are hardcoded List<double> bndL = new List<double>(); //the upper bounds for each variable being fit, these are hardcoded List<double> bndU = new List<double>(); //the scaling values for each variable being fit, these are hardcoded List<double> lScale = new List<double>(); //here I initialize the xList, upper and lower boundaries, and scales for each parameter being fit. //for Azeta if (input.FitAzeta == true) { xList.Add(input.Azeta); bndL.Add(double.NegativeInfinity); bndU.Add(double.PositiveInfinity); lScale.Add(1.0); } //for the origin if (input.FitOrigin == true) { xList.Add(0.0); bndL.Add(double.NegativeInfinity); bndU.Add(double.PositiveInfinity); lScale.Add(50.0);//changed from 200 } //for each mode for (int i = 0; i < input.nModes; i++) { //for Omega if (Modes[i].fitOmega == true) { xList.Add(Modes[i].modeOmega); bndL.Add(0.0); bndU.Add(double.PositiveInfinity); lScale.Add(50.0);//changed from 100 } //for D if (Modes[i].fitD == true) { xList.Add(Modes[i].D); bndL.Add(0.0); bndU.Add(double.PositiveInfinity); lScale.Add(3.0);//changed from 10 } //for K if (Modes[i].fitK == true) { xList.Add(Modes[i].K); bndL.Add(double.NegativeInfinity); bndU.Add(double.PositiveInfinity); lScale.Add(0.5);//changed from 1 } //for wexe if (Modes[i].fitWEXE == true) { xList.Add(Modes[i].wExe); bndL.Add(double.NegativeInfinity); bndU.Add(double.PositiveInfinity); lScale.Add(10.0);//change from 50 } } //then for cross-terms if (input.IncludeCrossTerms == true) { for (int i = 0; i < input.nModes; i++) { for (int j = 0; j < input.nModes; j++) { if (input.CrossTermFit[i, j] == true) { xList.Add(input.CrossTermMatrix[i, j]); bndL.Add(double.NegativeInfinity); bndU.Add(double.PositiveInfinity); if (j > i) { lScale.Add(500.0);//scale for bilinear coupling + cross quadratic, changed from 100 } if (j == i) { lScale.Add(50.0);//change from 250 } else { lScale.Add(50.0);//scale for cross anharmonic, change from 250 } } } } } //xVec for minLM optimizer double[] xVec = xList.ToArray(); //Upper/lower boundary arrays for minLM optimizer double[] lowBound = bndL.ToArray(); double[] upBound = bndU.ToArray(); //scaling array for minLM optimizer double[] scale = lScale.ToArray(); //Generate new Master Object //this is an ugly solution to the problem of using the ALGLIB routines since I need to pass a large amount of information //to this routine but can only include one object in the arguments. Therefore, I created the MasterObject just to store //this information which I pass to the ALGLIB routine. Where it's used, it is cast from object to a MasterObject. SOCJT run = new SOCJT(); MasterObject Masterly = new MasterObject(); //here, if using simple lanczos and wanting evecs, set pVector to false so that they are not calculated each step of the fit bool evecs = false; if (input.PrintVector && !input.BlockLanczos) { evecs = true; input.PrintVector = false; } Masterly.Initialize(run, input, Modes, inputFile, isQuad, userInput); //initialize and run MinLM algorithm double epsg = input.GTol; double epsf = input.FTol; double epsx = input.XTol; int maxits = input.MaxOptimizerSteps; alglib.minlmstate state; alglib.minlmreport rep; //alglib.ndimensional_func func; //alglib.ndimensional_grad gradient; //alglib.ndimensional_hess hessian; alglib.minlmcreatev(userInput.Length, xVec, input.Factor, out state); //if (input.calcHessian) //{ // state.needfgh = true; // //alglib.ndimensional_func func; // //alglib.ndimensional_grad grad; // //alglib.ndimensional_hess HessianMat; // //alglib.minlmoptimize(state, function, null, null, state.repnhess, Masterly); //} alglib.minlmsetbc(state, lowBound, upBound); alglib.minlmsetscale(state, scale); alglib.minlmsetcond(state, epsg, epsf, epsx, maxits); alglib.minlmsetxrep(state, true); //acc = 1, meaning it's on by default. Just leave that. //alglib.minlmsetacctype(state, 0); //if (input.calcHessian) //{ // alglib.minlmoptimize(state, func, gradient, hessian, null, Masterly); //} alglib.minlmoptimize(state, function, null, Masterly); alglib.minlmresults(state, out xVec, out rep); int report = rep.terminationtype; int iter = rep.iterationscount; //this calculates the covariance matrix from the Jacobian using cov[,] = {J^T * J}^-1 //initialize covariance matrix double[,] resultM = new double[state.x.Length, state.x.Length]; for (int u = 0; u < state.x.Length; u++) { for (int uu = 0; uu < state.x.Length; uu++) { resultM[u, uu] = 0.0; } } //calculate J^T * J and store in resultM alglib.rmatrixgemm(state.j.GetLength(1), state.j.GetLength(1), state.j.GetLength(0), 1.0, state.j, 0, 0, 1, state.j, 0, 0, 0, 0.0, ref resultM, 0, 0); //take inverse of resultM, replaces resultM int invInfo; alglib.matinvreport invReport = new alglib.matinvreport(); alglib.rmatrixinverse(ref resultM, out invInfo, out invReport); //now make correlation coefficient matrix double[,] corMat = new double[resultM.GetLength(0), resultM.GetLength(0)]; for (int i = 0; i < resultM.GetLength(0); i++) { for (int j = 0; j < resultM.GetLength(0); j++) { corMat[i, j] = resultM[i, j] / (Math.Sqrt(resultM[i, i] * resultM[j, j])); } } //if eigenvectors are needed when using naive lanczos, run SOCJT routine one more time to calculate them. if (evecs && !input.BlockLanczos) { Console.WriteLine("Calculating eigenvectors."); Masterly.nInput.PrintVector = true; Masterly.nSoc.SOCJTroutine(Masterly.nModes, Masterly.nIsQuad, Masterly.nInputFile, Masterly.nInput); //now assign the lanczosEVectors to those from the SOCJT routine lanczosEVectors = Masterly.nSoc.lanczosEVectors; basisSet = Masterly.nSoc.basisSet; } //make output soc = Masterly.nSoc; output = Masterly.nSoc.outp; //add something showing RMS error and parameters for each JT mode double[] error = ComparerVec(userInput, Masterly.nSoc.finalList, Masterly.nInput.Origin, true); StringBuilder file = new StringBuilder(); file.AppendLine("Fit report below..."); file.AppendLine("Termination Type: "); if (report == -9) { file.Append("Derivative correctness check failed"); } if (report == 1) { file.Append("Relative function improvement is no more than EpsF"); } if (report == 2) { file.Append("Relative step is no more than EpsX"); } if (report == 4) { file.Append("Gradient is no more than EpsG"); } if (report == 5) { file.Append("Maximum number of iterations was exceeded"); } if (report == 7) { file.Append("Stopping conditions are too stringent, further improvement is impossible"); } file.AppendLine(" "); file.AppendLine("Number of iterations: " + Convert.ToString(iter)); file.AppendLine("Number of times the eigenvalues were calculated: " + Convert.ToString(rep.nfunc)); file.AppendLine(" "); file.AppendLine("A * zeta e = " + Convert.ToString(Masterly.nInput.Azeta)); /* This is written for data analysis with the NFG program */ if (input.useNFG == true) { file.Append("\n" + "NFG_OUTPUT" + "\t"); for (int ii = 0; ii < Masterly.nInput.nModes; ii++) { double JTSE; if (Masterly.nModes[ii].IsAType == true) { JTSE = 0.0; } else { JTSE = Masterly.nModes[ii].D * Masterly.nModes[ii].modeOmega * (Masterly.nModes[ii].K + 1.0); } file.Append(String.Format("{0,7:0.00}", Masterly.nModes[ii].modeOmega) + "\t" + String.Format("{0,4:0.00}", Masterly.nModes[ii].wExe) + "\t" + String.Format("{0,5:0.0000}", Masterly.nModes[ii].D) + "\t" + String.Format("{0,5:0.0000}", Masterly.nModes[ii].K) + "\t" + String.Format("{0,4:0.00}", JTSE) + "\t"); } if (input.IncludeCrossTerms == true) { for (int i = 0; i < input.nModes; i++) { for (int j = 0; j < input.nModes; j++) { if (input.CrossTermMatrix[i, j] != 0.0 || input.CrossTermFit[i, j] == true) { if (i < j) { file.Append(String.Format("{0,10:0.0000}", input.CrossTermMatrix[i, j]) + "\t"); } else { file.Append(String.Format("{0,10:0.0000}", input.CrossTermMatrix[i, j]) + "\t"); } } } } } for (int ll = 0; ll < resultM.GetLength(0); ll++) { file.Append(String.Format("{0,10:0.0000}", Math.Sqrt(resultM[ll, ll])) + "\t"); } file.Append(String.Format("{0,10:0.000}", (Math.Sqrt(FitSOCJT.Comparer(userInput, Masterly.nSoc.finalList, Masterly.nInput.Origin) / userInput.Length)))); file.Append("\n" + "ELEVEL"); for (int ii = 0; ii < Masterly.nSoc.finalList.Length; ii++) { if (Masterly.nSoc.finalList[ii].JBlock == 0.5M) { file.Append("\t" + String.Format("{0,9:0.0000}", Masterly.nSoc.finalList[ii].Evalue)); } } file.Append("\n" + "A1LEVEL"); for (int ii = 0; ii < Masterly.nSoc.finalList.Length; ii++) { if (Masterly.nSoc.finalList[ii].JBlock == 1.5M && Masterly.nSoc.finalList[ii].IsA1 == true) { file.Append("\t" + String.Format("{0,9:0.0000}", Masterly.nSoc.finalList[ii].Evalue)); } } file.Append("\n" + "A2LEVEL"); for (int ii = 0; ii < Masterly.nSoc.finalList.Length; ii++) { if (Masterly.nSoc.finalList[ii].JBlock == 1.5M && Masterly.nSoc.finalList[ii].IsA1 == false) { file.Append("\t" + String.Format("{0,9:0.0000}", Masterly.nSoc.finalList[ii].Evalue)); } } file.AppendLine("\n"); } // end if useNFG == true file.AppendLine("Final Parameters for Each Mode:"); file.AppendLine("Mode #" + "\t" + "V(min)" + "\t" + "V(max)" + "\t" + "Omega(E)" + "\t" + "wexe" + "\t" + "D" + "\t" + "K" + "\t" + "JTSE" + "\t" + "Omega(A)" + "\t" + "A Type?"); for (int i = 0; i < Masterly.nInput.nModes; i++) { double JTSE; if (Masterly.nModes[i].IsAType == true) { JTSE = 0.0; } else { JTSE = Masterly.nModes[i].D * Masterly.nModes[i].modeOmega * (Masterly.nModes[i].K + 1.0); } file.AppendLine(Convert.ToString(i + 1) + "\t" + String.Format("{0,4:0}", 0) + "\t" + String.Format("{0,4:0}", Masterly.nModes[i].modeVMax) + "\t" + String.Format("{0,7:0.00}", Masterly.nModes[i].modeOmega) + "\t" + "\t" + String.Format("{0,4:0.00}", Masterly.nModes[i].wExe) + "\t" + String.Format("{0,5:0.0000}", Masterly.nModes[i].D) + "\t" + String.Format("{0,5:0.0000}", Masterly.nModes[i].K) + "\t" + String.Format("{0,4:0.00}", JTSE) + "\t" + String.Format("{0,7:0.00}", Masterly.nModes[i].modeAOmega) + "\t" + "\t" + Convert.ToString(Masterly.nModes[i].IsAType)); } file.AppendLine(" "); if (input.FitOrigin == true) { file.AppendLine("Origin Shift = " + String.Format("{0,8:0.000}", -1.0 * Masterly.nInput.Origin)); } file.AppendLine(" "); if (input.IncludeCrossTerms == true) { for (int i = 0; i < input.nModes; i++) { for (int j = 0; j < input.nModes; j++) { if (input.CrossTermMatrix[i, j] != 0.0 || input.CrossTermFit[i, j] == true) { if (i < j) { file.AppendLine("Mode " + Convert.ToString(i + 1) + " Mode " + Convert.ToString(j + 1) + " JT cross-term = " + String.Format("{0,10:0.0000}", input.CrossTermMatrix[i, j])); } else { file.AppendLine("Mode " + Convert.ToString(j + 1) + " Mode " + Convert.ToString(i + 1) + " AT cross-term = " + String.Format("{0,10:0.00}", input.CrossTermMatrix[i, j])); } } } } file.AppendLine(" "); } file.AppendLine("Fitting Results:"); if (input.FitOrigin == true) { file.AppendLine("Experimental values are shifted by " + String.Format("{0,8:0.000}", Masterly.nInput.Origin) + " wavenumbers."); } file.AppendLine("FitFile Value" + "\t" + "Calculated Value" + "\t" + "Exp - Calc" + "\t" + "(Exp - Calc)^2"); for (int i = 0; i < error.Length; i++) { file.AppendLine(String.Format("{0,13:0.000}", userInput[i].Evalue + Masterly.nInput.Origin) + "\t" + String.Format("{0,13:0.000}", userInput[i].Evalue + Masterly.nInput.Origin - error[i]) + "\t" + "\t" + String.Format("{0,9:0.000}", error[i]) + "\t" + String.Format("{0,11:0.000}", Math.Pow(error[i], 2D))); } file.AppendLine(" "); file.AppendLine("RMS Error = " + String.Format("{0,10:0.000}", (Math.Sqrt(FitSOCJT.Comparer(userInput, Masterly.nSoc.finalList, Masterly.nInput.Origin) / userInput.Length)))); file.AppendLine(" "); int l = 0; if (Masterly.nInput.FitAzeta == true) { file.AppendLine("Azeta StdDev = " + String.Format("{0,10:0.000000}", Math.Sqrt(resultM[l, l]))); l++; } if (Masterly.nInput.FitOrigin == true) { file.AppendLine("Origin StdDev = " + String.Format("{0,10:0.00}", Math.Sqrt(resultM[l, l]))); l++; } for (int i = 0; i < Masterly.nInput.nModes; i++) { if (Masterly.nModes[i].fitOmega == true) { file.AppendLine("Mode " + Convert.ToString(i + 1) + " Omega StdDev = " + String.Format("{0,10:0.00}", Math.Sqrt(resultM[l, l]))); l++; } if (Masterly.nModes[i].fitD == true) { file.AppendLine("Mode " + Convert.ToString(i + 1) + " D StdDev = " + String.Format("{0,10:0.0000}", Math.Sqrt(resultM[l, l]))); l++; } if (Masterly.nModes[i].fitK == true) { file.AppendLine("Mode " + Convert.ToString(i + 1) + " K StdDev = " + String.Format("{0,10:0.0000}", Math.Sqrt(resultM[l, l]))); l++; } if (Masterly.nModes[i].fitWEXE == true) { file.AppendLine("Mode " + Convert.ToString(i + 1) + " wexe StdDev = " + String.Format("{0,10:0.00}", Math.Sqrt(resultM[l, l]))); l++; } } if (Masterly.nInput.IncludeCrossTerms == true) { for (int i = 0; i < Masterly.nInput.nModes; i++) { for (int h = 0; h < Masterly.nInput.nModes; h++) { if (Masterly.nInput.CrossTermFit[i, h] == true) { if (i < h) { file.AppendLine("Mode " + Convert.ToString(i + 1) + " Mode " + Convert.ToString(h + 1) + " JT Term StdDev = " + String.Format("{0,10:0.0000}", Math.Sqrt(resultM[l, l]))); l++; } else { file.AppendLine("Mode " + Convert.ToString(h + 1) + " Mode " + Convert.ToString(i + 1) + " AT Term StdDev = " + String.Format("{0,10:0.00}", Math.Sqrt(resultM[l, l]))); l++; } } } } } file.AppendLine(" "); file.AppendLine("Correlation coefficient matrix:"); for (int i = 0; i < resultM.GetLength(0); i++) { file.AppendLine(""); file.Append("("); for (int j = 0; j < resultM.GetLength(0); j++) { if (j != 0) { file.Append(", "); } file.Append(String.Format("{0,8:0.000}", corMat[i, j])); } file.Append(")"); } file.AppendLine(" "); file.AppendLine(" "); output.Add(file.ToString()); output.AddRange(OutputFile.inputFileMaker(Masterly.nInput, Masterly.nModes)); return output; }
public static List<string> makeOutput(FileInfo input, List<double[,]> zMatrices, alglib.sparsematrix[] sHamMatrix, List<List<BasisFunction>> jBasisVecsByJ, List<double[]> eigenvalues, bool isQuad, Eigenvalue[] finalList, int[] IECODE, int[] ITER) { List<string> linesToWrite = new List<string>(); StringBuilder file = new StringBuilder(); decimal J = 0.5M; if (input.MinJBool == true) { J = input.minJ; } decimal Sigma = input.S * -1M; file.AppendLine(" "); file.AppendLine("Time Report:"); file.AppendLine("Matrix generation took " + String.Format("{0,10:0.00}", input.MatrixGenerationTime) + " seconds."); file.AppendLine("The Lanczos routines took " + String.Format("{0,10:0.00}", input.DiagonalizationTime) + " seconds."); file.AppendLine(" "); for (int i = 0; i < eigenvalues.Count; i++) { //add some asterisks here to make J and S stand out file.AppendLine("J = " + Convert.ToString(J)); file.AppendLine("Sigma = " + String.Format("{0,3:0.0}", Sigma)); //add some asterisks file.AppendLine(" "); if (eigenvalues[i] == null || eigenvalues[i].Length == 0) { file.AppendLine("Too small of a basis set to calculate these eigenvalues."); linesToWrite.Add(file.ToString()); file.Clear(); J++; continue; } double[] tempEvs = eigenvalues[i].ToArray(); for (int j = 0; j < tempEvs.Length; j++) { file.AppendLine("\t" + String.Format("{0,10:0.0000}", tempEvs[j])); }//this for loop writes the eigenvalues for each J level double[,] tempMat = zMatrices[i]; int numRows = sHamMatrix[i].innerobj.m; file.AppendLine(" "); file.AppendLine("Number of basis functions: " + Convert.ToString(numRows)); file.AppendLine("Number of non-zero matrix elements: " + Convert.ToString(sHamMatrix[i].innerobj.vals.Length)); file.AppendLine(" "); switch (IECODE[i]) { case 0: file.AppendLine("Lanczos routine successfully completed"); break; case 7: file.AppendLine("Max number of iterations in Lanczos routine was exceeded."); file.AppendLine("Not all eigenvalues have converged."); break; case 99: break; } file.AppendLine("Lanczos routine took " + Convert.ToString(ITER[i]) + " iterations to complete."); file.AppendLine(" "); if (input.PrintVector == true) { #region PrintVector for (int j = 0; j < tempEvs.Length; j++) { file.AppendLine(" " + "\r"); file.AppendLine("Eigenvalue" + "\t" + Convert.ToString(j + 1) + " = " + String.Format("{0,10:0.0000}", tempEvs[j])); file.AppendLine(" " + "\r"); file.AppendLine("Eigenvector: (Only vectors with coefficients larger than " + Convert.ToString(input.EigenvectorCoefficientMinimum) + " are shown)"); file.AppendLine(" "); vecBuilder(input, jBasisVecsByJ[i], file, tempMat, j, input.EigenvectorCoefficientMinimum, Sigma); } #endregion } if (input.PrintBasis == true) { #region PrintBasis file.AppendLine("\t" + "\r"); file.Append("Basis Fxn #" + "\t"); for (int h = 0; h < input.nModes; h++) { file.Append("v(" + Convert.ToString(h + 1) + ")" + "\t" + "l(" + Convert.ToString(h + 1) + ")" + "\t"); } file.Append("lambda" + "\t" + "Sigma"); for (int j = 0; j < jBasisVecsByJ[i].Count; j++)//goes through basis vectors { file.AppendLine("\t"); file.Append("\t" + Convert.ToString(j + 1)); for(int m = 0; m < input.nModes; m++)//goes through each mode { file.Append("\t" + " " + Convert.ToString(jBasisVecsByJ[i][j].modesInVec[m].V) + "\t" + String.Format("{0,3}", jBasisVecsByJ[i][j].modesInVec[m].L)); } file.Append("\t" + String.Format("{0,4}", jBasisVecsByJ[i][j].Lambda) + "\t" + String.Format("{0,3:0.0}", Sigma)); } #endregion }//end print Basis code if (input.PrintMatrix == true) { #region PrintMatrixSparse int nonZeroCount = 0; file.AppendLine("\t"); file.AppendLine("\r"); file.AppendLine("\t" + "Hamiltonian Matrix"); file.AppendLine("\t" + "Only upper triangle given"); file.AppendLine("Row" + "\t" + "Column" + "\t" + "Value"); int T0 = 0; int T1 = 0; int sRow = 0; int sCol = 0; double V = 0.0; for (; ; ) { if (alglib.sparseenumerate(sHamMatrix[i], ref T0, ref T1, out sRow, out sCol, out V) == false) { break; } else { file.AppendLine(Convert.ToString(sRow + 1) + "\t" + Convert.ToString(sCol + 1) + "\t" + String.Format("{0,10:0.0000}", V)); nonZeroCount++; } } file.AppendLine(" " + Convert.ToString(nonZeroCount) + " non-zero matrix elements"); #endregion } file.AppendLine("**********************************************************************"); file.AppendLine(" "); linesToWrite.Add(file.ToString()); file.Clear(); if (input.IncludeSO == true) { if (Sigma < input.S && (J - 1.5M) % 3 != 0) { Sigma++; } else { Sigma = input.S * -1M; J++; } } else { J++; } }//writes all evs to the file object file.AppendLine("#" + "\t" + "Final results showing all eigenvalues found"); file.AppendLine("\t" + "Eigenvalue" + "\t" + " j" + "\t" + "Sigma" + "\t" + "n_j" + "\t" + (input.useSeed ? "Symm" : "")); // + (input.BlockLanczos ? "\tSymm" : input.PrintVector ? "\tSymm" : "") + (input.Intensity ? "\tIntensity" : "")); int l = 0; for (int i = 0; i < finalList.Length; i++) { file.AppendLine(Convert.ToString(l + 1) + "\t" + String.Format("{0,9:0.0000}", finalList[i].Evalue) + "\t" + Convert.ToString(finalList[i].JBlock) + "\t" + String.Format("{0,3:0.0}", finalList[i].Sigma) + "\t" + Convert.ToString(finalList[i].Number) + "\t" + (input.useSeed ? (finalList[i].IsA1 ? "A1" : (finalList[i].JBlock == 1.5M ? "A2" : "E")) : "" )); // (\t" + Convert.ToString(finalList[i].IsA1) + (input.BlockLanczos ? (finalList[i].IsA1 ? "\t1" : "\t2") : input.PrintVector ? (finalList[i].IsA1 ? "\t1" : "\t2") : "") + (input.Intensity ? "\t" + String.Format("{0,9:0.0000}", Convert.ToString(finalList[i].Overlap)) : "")); l++; } linesToWrite.Add(file.ToString()); return linesToWrite; }
/// <summary> /// Method to sort eigenvalues in increasing order /// </summary> /// <param name="arr"> /// Eigenvalues to be sorted /// </param> private static void bubbleSort(ref Eigenvalue[] arr) { bool swapped = true; int j = 0; Eigenvalue tmp; while (swapped == true) { swapped = false; j++; for (int i = 0; i < arr.Length - j; i++) { if (arr[i].Evalue > arr[i + 1].Evalue) { tmp = arr[i]; arr[i] = arr[i + 1]; arr[i + 1] = tmp; swapped = true; }//end if }//end for }//end while }