<html>

<head><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- MyFirstUnitAd -->
<ins class="adsbygoogle"
     style="display:inline-block;width:970px;height:250px"
     data-ad-client="ca-pub-5778386704669218"
     data-ad-slot="1503492166"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Population</title>
</head>

<body>



<p align="center"><font size="6" color="#FF0000"><b>Math</b></font><b><font color="#FF0000" size="6"><span lang="en-ca">Matrix</span> 
Echelon</font></b></p>

<div align="left">
  <pre><b><font color="#ff0000" size="5">A.<span lang="en-ca">Third</span> Edition</font></b></pre>
</div>
<div align="left">
  <pre><b>This is the 3.5 edition of my Math</b><b><span lang="en-ca">Matrix class and I </span>corrected a big bug of its echelon method. And add a so-called</b></pre>
</div>
<div align="left">
  <pre><b>LHRRCC method which is abbreviation of &quot;Linear Homogeneous Recursive Relation with Constant Coefficient&quot;. </b></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">B</span>.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>Idea of program</b></font></span></pre>
</div>
<div align="left">
  <pre><b>1¡£ Basic idea: </b></pre>
</div>
<div align="left">
  <pre><b><span lang="en-ca">T</span>he echelon method actually can solve system functions. LHRRCC is like a joke. Do you know discrete mathematics?</b></pre>
</div>
<div align="left">
  <pre><b>2¡£ Program design: </b></pre>
</div>
<div align="left">
  <pre><b>The only problem with echelon is that when the diagonal entry is 0, you have to go to next row but remain same</b></pre>
</div>
<div align="left">
  <pre><b>column to make it 1, and after you come down to last row, if your column parameter doesnot reach the minimum of </b></pre>
</div>
<div align="left">
  <pre><b>both row and column, you have to go over. </b></pre>
</div>
<div align="left">
  <pre><b>3¡£ Major function:</b></pre>
  <blockquote>
    <blockquote>
  <pre><b>A.<span lang="en-ca">  void MathMatrix::echelon(int r, int c, bool reduced)</span></b></pre>
  <pre>Reduced means whether making all entries above diagonal 0's. </pre>
  <pre><b><span lang="en-ca">B. </span>Matrix&amp; LogicMatrix::warshall()</b></pre>
  <pre><span lang="en-ca"><b>Warshall algorithm is such simple, but not so easy to understand. </b></span></pre>
    </blockquote>
  </blockquote>
  <pre><b>4¡£ Further improvement£º	</b></pre>
  <pre>¡¡</pre>
</div>
<pre>#include &lt;iostream&gt;
#include &lt;cmath&gt;
#include &lt;fstream&gt;

using namespace std;

const int MaxRow = 10;
const int MaxCol = 10;
const double LIMIT = 0.01;


class Matrix
{
private:
	int rowNum;
	int colNum;
	double lst[MaxRow][MaxCol];
protected:
	void mul(int dest, double scalor);
	void mul(int source, int dest, double scalor);
public:
	Matrix();
	int row() const {return rowNum;}
	int col() const {return colNum;}
	void setRow(const int newRow) { rowNum = newRow;}
	void setCol(const int newCol) { colNum = newCol;}
	void display();
	double&amp; items(int r, int c);
	void initialize();
	void readFromFile(const char* fileName);
	Matrix&amp; operator = (Matrix other);
	Matrix&amp; transposition();	
};

class MathMatrix: public Matrix
{
public:
	void echelon(int r, int c, bool reduced=true);
	//Linear Homogeneous Recurrsive Relation with Constant Coefficients
	void LHRRCC(double* roots, double* initials, int degree);
	Matrix&amp; operator+(Matrix other);
	Matrix&amp; operator *(double i);
	Matrix&amp; operator *(Matrix otherMatrix);  
};

class LogicMatrix: public Matrix
{
protected:
	
public:</pre>
<pre>	Matrix&amp; operator &amp;&amp;(Matrix otherMatrix);
	Matrix&amp; operator ||(Matrix otherMatrix);
	Matrix&amp; power(int exponent);
	bool reflexive();
	bool symmetric();
	bool antiSymmetric();
	bool transitive();
	bool equivalent();
	bool partialOrder();
	Matrix&amp; transitiveClosure();
	Matrix&amp; reflexiveClosure();
	Matrix&amp; symmetricClosure();
	Matrix&amp; warshall();
};


int main()
{
	MathMatrix M;
	M.readFromFile(&quot;c:\\nick.txt&quot;);
	M.display();
	M.echelon(0,0);
	M.display();
	/*
	double roots[2] = {2,-1};
	double initials[2] = {2,7};
	MathMatrix M;
	M.LHRRCC(roots, initials, 2);
	M.display();
	M.echelon(0,0);
	
	M.display();
	*/
	return 0;
}
</pre>
<pre><a name="warshall"></a>Matrix&amp; LogicMatrix::warshall()
{
	int n = row(); //n is dimention of matrix
	for (int k=0; k&lt;n; k++)
	{
		for (int r=0;r&lt;n; r++)
		{
			for (int c=0; c&lt;n; c++)
			{
				items(r,c) = items(r,c)|| items(r,k) &amp;&amp; items(k,c);
			}
		}
	}
	return *this;
}


</pre>
<pre>Matrix&amp; LogicMatrix::symmetricClosure()
{
	for (int r=0; r&lt; row(); r++)
	{
		for (int c=0; c&lt; col(); c++)
		{
			if (items(r,c)==1)
			{
				items(c, r) = 1;
			}
		}
	}
	return *this;
}

Matrix&amp; LogicMatrix::reflexiveClosure()
{
	for (int i=0; i&lt;row(); i++)
	{
		items(i, i) = 1;
	}
	return *this;
}


bool LogicMatrix::partialOrder()
{
	return reflexive()&amp;&amp;antiSymmetric()&amp;&amp;transitive();
}


bool LogicMatrix::equivalent()
{
	return reflexive()&amp;&amp;symmetric()&amp;&amp;transitive();
}


Matrix&amp; LogicMatrix::transitiveClosure()
{
	int dim = col();
	LogicMatrix N;
	N = *this;
	for (int i = 1; i&lt;=dim; i++)
	{
		(Matrix)N = (Matrix)(N ||power(i));
	}
	*this = N;
	return *this;
}


Matrix&amp; LogicMatrix::operator ||(Matrix otherMatrix)
{
	int dim = col();
	for (int r = 0; r&lt; dim; r++)
	{
		for (int c=0; c&lt; dim; c++)
		{
			items(r,c) = (int)items(r,c) ||(int)otherMatrix.items(r, c);
		}
	}
	return *this;
}


bool LogicMatrix::reflexive()
{
	bool result = true;
	for (int i =0; i&lt;col(); i++)
	{
		result = result&amp;&amp;items(i, i);
	}
	return result;
}

bool LogicMatrix::symmetric()
{
	int dim = col();  //since the function will be called nxn times, better use variable.
	for (int r = 0; r&lt; dim; r++)
	{
		for (int c = r; c&lt; dim; c++)
		{			
			if ((int)items(r,c)^(int)items(c,r))//exclusive or
			{
				return false;
			}
		}
	}
	return true;
}

bool LogicMatrix::antiSymmetric()
{
	int dim = col();
	for (int r =0; r&lt; dim; r++)
	{
		for (int c = r; c&lt; dim; c++)
		{
			if (items(r,c)&amp;&amp;items(c,r))
			{
				if (r != c)
				{
					return false;
				}
			}
		}
	}
	return true;
}

bool LogicMatrix::transitive()
{
	int dim = col();
	for (int r =0; r&lt; dim; r++)
	{
		for (int c=0; c&lt; dim; c++)
		{
			if (items(r,c))//if find an entry which is 1's
			{
				for (int i =0; i&lt; dim; i++) // try to find in c'th row 
				{
					if (items(c, i))
					{
						if (!items(r, i))
						{
							return false;
						}
					}
				}
			}
		}
	}
	return true;
}

Matrix&amp; LogicMatrix::operator &amp;&amp;(Matrix otherMatrix)
{
	bool dummy=false;
	int dim = col();  //as this function is used so many times, better use variable, 
	for (int r =0; r&lt;dim; r++)
	{
		for (int c =0; c&lt;dim; c++)
		{
			for (int i=0; i&lt;dim; i++)
			{
				dummy = dummy||(items(r,i)&amp;&amp;otherMatrix.items(i, c));
			}
			items(r, c) = dummy;
			dummy = false;
		}
	}
	return *this;
}

Matrix&amp; LogicMatrix::power(int exponent)
{
	Matrix N;
	N = *this; //I have to copy a temp Matrix to keep original one
	for (int i=1; i&lt;exponent; i++)
	{
		this-&gt;operator &amp;&amp;(N);
	}
	return (*this);
}

Matrix&amp; Matrix::transposition()
{
	double hold;
	int temp;
	for (int r =0; r&lt; rowNum; r++)
	{
		for (int c=0; c&lt; r; c++)
		{
			hold = lst[r][c];
			lst[r][c] = lst[c][r];
			lst[c][r] = hold;
		}
	}
	temp = rowNum;
	rowNum = colNum;
	colNum = temp;
	return (*this);
}


void MathMatrix::LHRRCC(double *roots, double* initials, int degree)
{
	for (int r=0; r&lt;degree; r++)
	{
		for (int c=0;c&lt;degree; c++)
		{
			if (r==0)
			{
				items(r,c) = 1;
			}
			else
			{
				items(r,c) = items(r-1,c)*roots[c];
			}
		}
		items(r,c) = initials[r];
	}
	setRow(degree);
	setCol(degree+1);
}

Matrix&amp; MathMatrix::operator +(Matrix other)
{
	if (row()!= other.row() || col()!= other.col())
	{
		cout&lt;&lt;&quot;\nTwo matrix has different row or col number!\n&quot;;
		return (*this);
	}
	else
	{
		for (int r=0; r&lt; row(); r++)
		{
			for (int c=0; c&lt; col(); c++)
			{
				items(r, c) +=other.items(r, c);
			}
		}
		return (*this);
	}
}

Matrix&amp; MathMatrix::operator *(Matrix other)
{
	double total =0;
	Matrix temp;
	temp.setRow(row());
	temp.setCol(other.col());

	if (col()!=other.row())
	{
		cout&lt;&lt;&quot;\nrow &amp; col are not same!\n&quot;;
	
	}
	else
	{
		for (int r =0; r&lt; row(); r++)
		{
			for (int c=0; c&lt;other.col(); c++)
			{
				total =0;
				for (int i=0; i&lt;col(); i++)
				{
					total += items(r,i) * other.items(i, c);
				}
				temp.items(r, c) = total;
			}
		}
		(Matrix)(*this) = temp;
	
	}
	return (*this);
}
				
Matrix&amp; Matrix::operator =(Matrix other)
{
	setRow(other.row());
	setCol(other.col());
	for (int r=0; r&lt; other.row(); r++)
	{
		for (int c=0; c&lt; other.col(); c++)
		{
			lst[r][c] = other.items(r, c);
		}
	}
	
	return (*this);
}

void Matrix::mul(int dest, double scalor)
{
	for (int c=0; c&lt; colNum; c++)
	{
		lst[dest][c] *= scalor;
	}
}

Matrix&amp; MathMatrix::operator *(double i)
{
	for (int r=0; r&lt;row(); r++)
	{
		for (int c=0; c&lt;col(); c++)
		{
			items(r, c) *= i;
		}
	}
	return (*this);
}

void MathMatrix::echelon(int r, int c, bool reduced)
{
	if (r&lt;row()&amp;&amp;c&lt;col()&amp;&amp;c&lt;row())
	{
		if (items(r, c) !=0)
		{
			mul(r, 1/items(r,c));   //make it 1 for this row
			for (int i=(!reduced?r+1:0); i&lt; row(); i++)
			{
				if (i!=r)
				{
					mul(r, i, -items(i,c));
				}
			}	
			echelon(r+1, c+1, reduced);
		}
		else
		{
			echelon(r+1, c, reduced);
		}
	}
	else
	{
		if (c&lt;row()&amp;&amp;c&lt;col())
		{
			echelon(0, c, reduced);
		}
	}
}

void Matrix::mul(int source, int dest, double scalor)
{
	for (int c=0; c&lt; colNum; c++)
	{
		lst[dest][c] += lst[source][c]*scalor;
	}
}


double&amp; Matrix::items(int r, int c)
{
	return lst[r][c];
}

void Matrix::readFromFile(const char* fileName)
{
	int r=0, c=0;
	char ch;
	ifstream f;
	f.open(fileName);
	while (!f.eof())
	{
		ch = f.peek();
		
		if (ch!=10)  //return char
		{
			
			f&gt;&gt;lst[r][c];
			c++;
			if (c&gt;colNum)
				colNum = c;
		}
		else
		{
			f.ignore();
			r++;
			setCol(c);
			c =0;
		}
	}
	if (r!=0)
	{
		setRow(r+1);
	}
}


void Matrix::initialize()
{
	for (int r=0; r &lt; rowNum; r++)
	{
		for (int c=0; c&lt; colNum; c++)
		{
			lst[r][c] = r*2+c;
		}
	}	
}


void Matrix::display()
{
//	int temp;
	long preFlag;
	preFlag = cout.flags();
//	temp = cout.precision(4);
//	cout.setf(ios::fixed);
	
	cout&lt;&lt;&quot;\nrow\\col&quot;;
	for (int c=0; c&lt; colNum; c++)
	{
		cout&lt;&lt;&quot;  &quot;&lt;&lt;c;
	}
	cout&lt;&lt;&quot;\n\n&quot;;
	for (int r = 0; r&lt; rowNum; r++)
	{
		cout&lt;&lt;r&lt;&lt;&quot;\t &quot;;
		for (c = 0; c&lt; colNum; c++)
		{
			cout&lt;&lt;(fabs(lst[r][c])&lt;LIMIT?0:lst[r][c])&lt;&lt;&quot;  &quot;;			
		}
		cout&lt;&lt;endl;
	}
//	cout.precision(temp);
	cout.flags(preFlag);
}

Matrix::Matrix()
{
	rowNum = 5;
	colNum = 5;
	initialize();
}
</pre>
<pre></pre>
<pre></pre>

<p>¡¡          


</p>

<p><span lang="en-ca">The original matrix is like following:<a name="output"></a></span>(pls 
pay attention that the diagonal entry in second row is 0. It prevents you from 
making all diagonal entries to be 1. But still you have to solve it by going to 
next row but</p>

<p>keeping the same column. When you finish all rows, if your column has not 
reached the minimum of&nbsp; both row and </p>

<p>column, you have to go on. Understand?)</p>

<p>¡¡</p>

<p>1 6 2 4<br>
0 0 1 5<br>
2 0 0 6</p>

<p>¡¡</p>

<p><span lang="en-ca">And the output file is like <a href="nickMatrix.txt">
following</a>:</span></p>

<pre>row\col  0  1  2  3

0        1  6  2  4
1        0  0  1  5
2        2  0  0  6

row\col  0  1  2  3

0        1  0  0  3
1        0  0  1  5
2        0  1  0  -1.5
Press any key to continue
</pre>
<p>¡¡</p>
<p><a name="LHRRCC"></a>As for LHRRCC, you have to input two double array. The 
first one is the n distinct roots and the second is the </p>
<p>n initial value of Recursive Relation. Got it?<br>
<br>
¡¡</p>

<p><span lang="en-ca"> <br>
¡¡</span></p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                   
&nbsp;&nbsp;&nbsp; <a href="Monopoly.htm">                  







                       <img src="picture/back.gif" style="border: medium none" alt="back.gif (341 bytes)" width="32" height="35"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<a href="index.htm"><img src="picture/up.gif" style="border: medium none" alt="up.gif (335 bytes)" width="35" height="32"></a>       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                         
<img src="picture/next.gif" style="border: medium none" alt="next.gif (337 bytes)" width="32" height="35">          


</p>

</body>

</html>