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