I’m taking a discrete math class. And I’m bored to tears.

Its not totally boring the first 10 mins of class are ok. That’s when I learn something new then the reset of the class is spent repeating the first 10 mins until everyone “gets it.” I can tell I’m not the only one; there are a few others as board as me.

Its not the teacher’s fault he actually makes this stuff interesting and is very good at explaining it at a level that my 10 year old could understand. Some people just don’t get it.

So here I am board with my laptop trying to look as if I’m paying attention and I get this bright idea. Make the computer do my homework for me. Yes I’ve written some code in C# that will calculate the properties of a relation of two sets. I started working on code to build the set but found out that it was already in the C# library so I scraped it.

Here is my Relation Class:

    class Relation<T> : Set<Pair<T>>
    {
        private Set<T> _A;
        private Set<T> _B;

        public Relation(Set<T> A, Set<T> B)
        {
            _A = A;
            _B = B;
        }

        public bool Add(T a, T b)
        {
            return Add(new Pair<T>(a, b));
        }

        new public bool Add(Pair<T> item)
        {
            if (_A.Contains(item.a) && _B.Contains(item.b))
            {
                return base.Add(item);
            }
            else
            {
                return false;
            }
        }

        public bool IsReflexive()
        {
            IEnumerator<Pair<T>> ptr = GetEnumerator();

            while (ptr.MoveNext())
            {
                Pair<T> op = ptr.Current;

                if (!op.a.Equals(op.b))
                {
                    return false;
                }
            }

            return true;
        }

        public bool IsSymmetric()
        {
            IEnumerator<Pair<T>> ptr = GetEnumerator();

            while (ptr.MoveNext())
            {
                Pair<T> op = ptr.Current;

                if (!Contains(new Pair<T>(op.b, op.a)))
                {
                    return false;
                }
            }

            return true;
        }

        public bool IsAntisymmetric()
        {
            IEnumerator<Pair<T>> ptr = GetEnumerator();

            while (ptr.MoveNext())
            {
                Pair<T> op = ptr.Current;

                if (Contains(new Pair<T>(op.b, op.a)))
                {
                    return false;
                }
            }

            return true;
        }

        public bool IsTransitive()
        {
            IEnumerator<Pair<T>> ptr_x = GetEnumerator();

            while (ptr_x.MoveNext())
            {
                Pair<T> x = ptr_x.Current;

                IEnumerator<Pair<T>> ptr_y = GetEnumerator();

                while (ptr_y.MoveNext())
                {
                    Pair<T> y = ptr_y.Current;

                    if (x.b.Equals(y.a))
                    {
                        if (!Contains(new Pair<T>(x.a, y.b)))
                        {
                            return false;
                        }
                    }
                }
            }

            return true;
        }

        public Set<T> SetA
        {
            get
            {
                return _A;
            }
        }

        public Set<T> SetB
        {
            get
            {
                return _B;
            }
        }

        public Matrix<bool> GetMatrix()
        {
            T[] A = _A.ToArray();
            T[] B = _B.ToArray();

            Matrix<bool> M = new Matrix<bool>(A.Length, B.Length);

            Array.Sort(A);
            Array.Sort(B);

            for (int a = 0; a < A.Length; a++)
            {
                for (int b = 0; b < B.Length; b++)
                {
                    if (Contains(new Pair<T>(A[a], B[b])))
                    {
                        M.Set(a, b, true);
                    }
                    else
                    {
                        M.Set(a, b, false);
                    }
                }
            }

            return M;
        }
    }

I also created a Matrix Class

    class Matrix<T> where T : struct
    {
        private int _rows;
        private int _cols;
        private T[,] _data;

        public Matrix(int rows, int cols)
        {
            _rows = rows;
            _cols = cols;
            _data = new T[_rows, _cols];
        }

        public Matrix(T[,] data)
            : this(data.GetLength(0), data.GetLength(1))
        {
            Set(data);
        }

        public void Set(T[,] data)
        {
            for (int r = 0; r < _rows; r++)
            {
                for (int c = 0; c < _cols; c++)
                {
                    _data[r, c] = data[r, c];
                }
            }
        }

        public void Set(int row, int col, T value)
        {
            _data[row, col] = value;
        }

        public T Get(int row, int col)
        {
            return _data[row, col];
        }

        public Matrix<T> Join(Matrix<T> rhs)
        {
            if (!(default(T) is bool))
            {
                throw new Exception("join can only be used on the Boolean data type");
            }

            if ((_rows != rhs._rows) || (_cols != rhs._cols))
            {
                throw new Exception("both matrices have to be the same size");
            }

            Matrix<T> tmp = new Matrix<T>(rhs._rows, rhs._cols);

            for (int r = 0; r < rhs._rows; r++)
            {
                for (int c = 0; c < rhs._cols; c++)
                {
                    tmp.Set(r, c, (dynamic)this.Get(r, c) || (dynamic)rhs.Get(r, c));
                }
            }

            return tmp;
        }

        public Matrix<T> Meet(Matrix<T> rhs)
        {
            if (!(default(T) is bool))
            {
                throw new Exception("meet can only be used on the Boolean data type");
            }

            Matrix<T> tmp = new Matrix<T>(rhs._rows, rhs._cols);

            for (int r = 0; r < rhs._rows; r++)
            {
                for (int c = 0; c < rhs._cols; c++)
                {
                    tmp.Set(r, c, (dynamic)this.Get(r, c) && (dynamic)rhs.Get(r, c));
                }
            }

            return tmp;
        }

        public static Matrix<T> operator +(Matrix<T> lhs, Matrix<T> rhs)
        {
            if (default(T) is bool)
            {
                throw new Exception("join cannot be used on the Boolean data type");
            }

            if ((lhs._rows != rhs._rows) || (lhs._cols != rhs._cols))
            {
                throw new Exception("both matrices have to be the same size");
            }

            Matrix<T> tmp = new Matrix<T>(lhs._rows, lhs._cols);

            for (int r = 0; r < lhs._rows; r++)
            {
                for (int c = 0; c < lhs._cols; c++)
                {
                    tmp.Set(r, c, (dynamic)lhs.Get(r, c) + (dynamic)rhs.Get(r, c));
                }
            }

            return tmp;
        }

        public static Matrix<T> operator -(Matrix<T> lhs, Matrix<T> rhs)
        {
            if (default(T) is bool)
            {
                throw new Exception("join cannot be used on the Boolean data type");
            }

            if ((lhs._rows != rhs._rows) || (lhs._cols != rhs._cols))
            {
                throw new Exception("both matrices have to be the same size");
            }

            Matrix<T> tmp = new Matrix<T>(lhs._rows, lhs._cols);

            for (int r = 0; r < lhs._rows; r++)
            {
                for (int c = 0; c < lhs._cols; c++)
                {
                    tmp.Set(r, c, (dynamic)lhs.Get(r, c) - (dynamic)rhs.Get(r, c));
                }
            }

            return tmp;
        }

        public static Matrix<T> operator *(Matrix<T> lhs, Matrix<T> rhs)
        {
            if (lhs._cols != rhs._rows)
            {
                throw new Exception("matrices are not conformable; lhs columns has to equal rhs rows");
            }

            Matrix<T> tmp = new Matrix<T>(lhs._rows, rhs._cols);

            for (int r = 0; r < lhs._rows; r++)
            {
                for (int c = 0; c < rhs._cols; c++)
                {
                    dynamic value = default(T);

                    for (int x = 0; x < lhs._cols; x++)
                    {
                        if (value is bool)
                        {
                            value = value || ((dynamic)lhs.Get(r, x) && (dynamic)rhs.Get(x, c));
                        }
                        else
                        {
                            value = value + (dynamic)lhs.Get(r, x) * (dynamic)rhs.Get(x, c);
                        }
                    }

                    tmp.Set(r, c, value);
                }
            }

            return tmp;
        }

        public static Matrix<T> operator *(Matrix<T> lhs, T rhs)
        {
            if (default(T) is bool)
            {
                throw new Exception("join cannot be used on the Boolean data type");
            }

            Matrix<T> tmp = new Matrix<T>(lhs._rows, lhs._cols);

            for (int r = 0; r < lhs._rows; r++)
            {
                for (int c = 0; c < lhs._cols; c++)
                {
                    tmp.Set(r, c, (dynamic)lhs.Get(r, c) * (dynamic)rhs);
                }
            }

            return tmp;
        }

        public Matrix<T> Transpose()
        {
            Matrix<T> tmp = new Matrix<T>(this._cols, this._rows);

            for (int r = 0; r < _rows; r++)
            {
                for (int c = 0; c < _cols; c++)
                {
                    tmp.Set(c, r, Get(r, c));
                }
            }

            return tmp;
        }

        override public String ToString()
        {
            String m = String.Empty;

            for (int r = 0; r < _rows; r++)
            {
                if (r > 0)
                {
                    m += "\n";
                }

                m += "[";

                for (int c = 0; c < _cols; c++)
                {
                    if (c > 0)
                    {
                        m += " ";
                    }

                    T value = Get(r, c);

                    if (value is bool)
                    {
                        m += (dynamic)value == true ? "1" : "0";
                    }
                    else
                    {
                        m += value.ToString();
                    }
                }

                m += "]";
            }

            return m;
        }
    }

Tags: