【刘庆源码共享】稀疏线性系统求解算法MGMRES(m) 之 赋值类定义(C++)

来源:互联网 发布:运营商网络是要收费吗 编辑:程序博客网 时间:2024/05/17 06:40

/* 
 * Copyright (c) 2009 湖南师范大学数计院 一心飞翔项目组
 * All Right Reserved
 *
 * 文件名:EvalFile.cpp
 * 摘  要:定义EvalFile类的各个方法
 *
 * 作  者:刘 庆
 * 完成日期:2009年3月30日
 *
*/

#include <math.h>
#include <iostream>
#include <fstream>
#include "EvalFile.h"
#include "MyException.h"

using namespace std;

EvalFile::EvalFile(char* fileName)
{
 try{
  SetFile(fileName);
 }
 catch(FileNotFoundException &e)
 {
  e.PrintMessage();
 }
}
EvalFile::~EvalFile()

 Close();
}
void EvalFile::SetFile(char* fileName)
{
 Close();
 infile.open(fileName, ios::in);
 if(!infile)
  throw FileNotFoundException("File Not Found Exception!");
}
void EvalFile::Close()
{
 if(!infile)
  infile.close();
}

int EvalFile::SetWithSub(Matrix &matrix)
{
 /* 从文件中读取总非零元素个数、总行数和总列数 */
 long temp = 0;
 try
 { 
  infile>>temp;
  matrix.SetTotal_elem(temp);
  infile>>temp;
  matrix.SetTotal_ln(temp);
  infile>>temp;
  matrix.SetTotal_col(temp);
 }
 catch(exception e)
 {
  cout<<"文件读取错误!"<<endl;
  return 0;
 }
 matrix.SetTotal_elem(matrix.GetTotal_elem()+matrix.GetTotal_ln());
 matrix.Init(0.0);  /* 初始化矩阵信息,替data,num分配空间及其所有元素赋值为0 */
 matrix.SetTotal_elem(matrix.GetTotal_elem()-matrix.GetTotal_ln());
 Double tempvalue = 0;
 long templn = 0, tempcol = 0, offset = 1;
 long *ln = new long[matrix.GetTotal_elem()];  /* 辅助变量 存储行坐标 */
 long *num = new long[matrix.GetTotal_ln()];
 long i=0;
 for(i=0; i<matrix.GetTotal_ln(); i++)
  num[i] = 0;

 /* 在数据中只记录非零元素,而假若对角线上有0,则也要为其开辟空间 */
 long DiagonalZero = matrix.GetTotal_ln();
 /* 从文件中读取元素信息
 /* 如果文件中的数据是按照行优先的顺序存储的,那么此种方法读取的数据便是
 /* 有序的,及行坐标按照从小到大的顺序排列,针对每个行坐标,纵坐标也是有序的 */
 for(i=0; i<matrix.GetTotal_elem(); i++)
 {
  try
  {
   infile>>tempvalue>>templn>>tempcol;
   if(tempvalue==0)
    tempvalue = 0;
  }
  catch(exception e)
  {
   cout<<"文件读取错误!"<<endl;
   return 0;
  }
  if(templn == tempcol)
  { /* 相等则为对角元素 */
   matrix.data[templn].value = tempvalue;
   DiagonalZero--;
  }
  else
  {     /* 不等则为非对角元素 */
   if(tempvalue!=0)
   {
    matrix.data[matrix.GetTotal_ln()+offset].value = tempvalue;
    matrix.data[matrix.GetTotal_ln()+offset].index = tempcol;
    ln[offset-1] = templn;
    num[templn]++;
    offset++; 
   }
  }
 }
 matrix.SetTotal_elem(matrix.GetTotal_ln()+offset-1);
 /* 第一行的第一个非零非对角元素必定排在data[]中的第total_ln+1 */
 matrix.data[0].index = matrix.GetTotal_ln()+1;
 /* data[total_ln].value 赋值为0,或者其他信息,或者空置 */
 matrix.data[matrix.GetTotal_ln()].value = 0;
 /* data[total_ln].index 必定为 总非零元素总个数+1,帮助控制循环 */
 matrix.data[matrix.GetTotal_ln()].index = matrix.GetTotal_elem()+1;
 /* 计算每行第一个非零非对角元素在data[]中的序列号 */
 for(i=1; i<matrix.GetTotal_ln()+1; i++)
  matrix.data[i].index = matrix.data[i-1].index+num[i-1];

 /* 将行标排序 */
// matrix.QuickSortLn(ln, 0, matrix.GetTotal_elem()-matrix.GetTotal_ln()-1);
 /* 针对每个行标 将其列标排序 */
// for(i=0; i<matrix.GetTotal_ln(); i++)
//  matrix.QuickSortCol(matrix.data[i].index, matrix.data[i+1].index-1);

 delete []ln;
 ln = 0;
 delete []num;
 num = 0;
 return 1;
}
/* 文件里的数据不包含下标信息,适合于创建n行一列矩阵 */
int EvalFile::SetWithoutSub(Matrix& matrix){
 try
 {
  /* 从文件中读取总非零元素个数、总行数和总列数 */
  long temp = 0;
  infile>>temp;
  matrix.SetTotal_elem(temp);
  infile>>temp;
  matrix.SetTotal_ln(temp);
  infile>>temp;
  matrix.SetTotal_col(temp);
 }
 catch(exception e)
 {
  cout<<"文件读取错误!"<<endl;
  return 0;
 }
 matrix.SetTotal_elem(matrix.GetTotal_elem()+matrix.GetTotal_ln());
 matrix.Init(0.0);  /* 初始化矩阵信息,替data,num分配空间及其所有元素赋值为0 */
 matrix.SetTotal_elem(matrix.GetTotal_elem()-matrix.GetTotal_ln());
 long* num = new long[matrix.GetTotal_ln()];
 long i=0;
 for(i = 0; i<matrix.GetTotal_ln(); i++)
  num[i] = 0;

 long zero=0;
 for(i=0; i<matrix.GetTotal_elem(); i++)
 {
  try
  {
   if(i==0){
    infile>>matrix.data[i].value;
    if(matrix.data[i].value==0)
     matrix.data[i].value = 0;
   }
   else
   {
    infile>>matrix.data[matrix.GetTotal_ln()+i-zero].value;
    if(matrix.data[matrix.GetTotal_ln()+i-zero].value!=0)
    {
     matrix.data[matrix.GetTotal_ln()+i-zero].index = 0;
     num[i]++;
    }else
     zero++;
   }
  }
  catch(exception e)
  {
   cout<<"文件读取错误!"<<endl;
   return 0;
  }
 }
 matrix.data[0].index = matrix.GetTotal_ln()+1;
 for(i = 1; i<matrix.GetTotal_ln()+1; i++)
  matrix.data[i].index = matrix.data[i-1].index+num[i-1];
 matrix.SetTotal_elem(matrix.GetTotal_elem()+matrix.GetTotal_ln()-1-zero);
 delete[] num;
 num = NULL;
 return 1;
}

/* 将数组中data的数据存储为matrix矩阵 适合创建n行1列的矩阵 */
int EvalFile::SEtWithVector(Matrix &matrix, const Node data, long totalLn, long nonZero)
{
 if(data.point==0)
 {
  cout<<"参数data中无数据!"<<endl;
  return 0;
 }

 matrix.SetTotal_ln(totalLn);
 matrix.SetTotal_col(1);
 matrix.SetTotal_elem(nonZero+matrix.GetTotal_ln());
 matrix.Init(0.0);  /* 初始化矩阵信息,替data,num分配空间及其所有元素赋值为0 */
 matrix.SetTotal_elem(matrix.GetTotal_elem()-matrix.GetTotal_ln());

 long* num = new long[matrix.GetTotal_ln()];

 long i=0;
 for(i = 0; i<matrix.GetTotal_ln(); i++)
  num[i] = 0;

 long zero=0;
 for(i=0; i<matrix.GetTotal_elem(); i++)
 {
  if(i==0)
  {
   if(data[i].value==0)
    matrix.data[i].value = 0;
   else
    matrix.data[i].value = data[i].value;
  }
  else
  {
   if(data[i].value!=0)
   {
    matrix.data[matrix.GetTotal_ln()+i-zero].index = 0;
    matrix.data[matrix.GetTotal_ln()+i-zero].value = data[i].value;
    num[i]++;
   }
   else
    zero++;
  }
 }
 matrix.data[0].index = matrix.GetTotal_ln()+1;
 for(i = 1; i<matrix.GetTotal_ln()+1; i++)
  matrix.data[i].index = matrix.data[i-1].index+num[i-1];
 delete[] num;
 num = NULL;

 return 1;
}

原创粉丝点击