Example #1
0
        /// <summary>
        /// Generates a resource consumption pattern matrix
        /// </summary>
        /// <param name="ip">The current InputParameters object</param>
        private RectangularMatrix GenResConsPat(InputParameters ip)
        {
            bool throwAway;
            int  numThrows = 0;

            RectangularMatrix outputMatrix;

            do
            {
                throwAway    = false;
                outputMatrix = new RectangularMatrix(ip.RCP, ip.CO);

                // Flowchart 5.1(a): Generate vector X
                RowVector X = GenRandNumbers.GenStdNormalVec(ip.CO);

                // The following code is used in both 5.1(b) and 5.1(c):
                RowVector[] Y = new RowVector[ip.RCP - 1];
                RowVector[] Z = new RowVector[Y.Length];

                for (int i = 0; i < Y.Length; ++i)
                {
                    Y[i] = GenRandNumbers.GenStdNormalVec(ip.CO);
                }

                // Flowchart 5.1(b): Generate (DISP1 - 1) vectors Y
                // Then create Z vectors based on X and Y
                double COR1 =
                    GenRandNumbers.GenUniformDbl(ip.COR1LB, ip.COR1UB);
                double sqrtConstant1 = Math.Sqrt(1 - COR1 * COR1);
                for (int i = 0; i < ip.DISP1 - 1; ++i)
                {
                    Z[i] = (COR1 * X) + (sqrtConstant1 * Y[i]);
                }

                // Flowchart 5.1(c): Generate (RCP - DISP1) vectors Y
                // Then create the remaining Z vectors based on X and Y
                double COR2 =
                    GenRandNumbers.GenUniformDbl(ip.COR2LB, ip.COR2UB);
                double sqrtConstant2 = Math.Sqrt(1 - COR2 * COR2);
                for (int i = ip.DISP1 - 1; i < Z.Length; ++i)
                {
                    Z[i] = (COR2 * X) + (sqrtConstant2 * Y[i]);
                }

                // Flowchart 5.1(d):
                // Take the absolute values of X and the Z's and
                // scale both by 10.0.
                X = X.Map(x => 10.0 * Math.Abs(x));
                for (int i = 0; i < Z.Length; ++i)
                {
                    Z[i] = Z[i].Map(z => 10.0 * Math.Abs(z));
                }

                // Round X and the Z's to integers
                X = X.Map(x => Math.Ceiling(x));
                for (int i = 0; i < Z.Length; ++i)
                {
                    Z[i] = Z[i].Map(z => Math.Ceiling(z));
                }

                // Flowchart 5.1(e):
                // Now punch out values in the Z's at random to make
                // the matrix sparse
                for (int i = 0; i < Z.Length; ++i)
                {
                    Z[i] = Z[i].Map(x => ((GenRandNumbers.GenUniformDbl() < D) ? x : 0.0));
                }

                // Flowchart 5.1(f):
                // Copy X into first row of outputMatrix.
                outputMatrix.CopyRowInto(X, 0);
                // Copy the Z's into the remaining rows of outputMatrix.
                for (int i = 0; i < Z.Length; ++i)
                {
                    outputMatrix.CopyRowInto(Z[i], i + 1);
                }

                // Ensure that the first row has no zeros
                // There is a very small probability of getting a zero with
                // the Ceiling function, but given that there are a finite
                // number of double-precision floating point numbers, it
                // is not impossible to get a 0.0.
                double[] firstRow = outputMatrix.Row(0).ToArray();

                if (Array.Exists(firstRow, x => x == 0.0))
                {
                    throwAway = true;
                    break;
                }

                // Ensure that each *row* has at least one non-zero entry
                for (int i = 0; i < outputMatrix.RowCount; ++i)
                {
                    double[] nextRow = outputMatrix.Row(i).ToArray();

                    if (Array.TrueForAll(nextRow, x => x == 0.0))
                    {
                        throwAway = true;
                        break;
                    }
                }

                // Ensure that each *column* has at least one non-zero entry
                // Technically, this check is redundant, as the first row, X,
                // is not supposed to have any zero entries. But just to be
                // on the safe side...
                for (int j = 0; j < outputMatrix.ColumnCount; ++j)
                {
                    double[] nextCol = outputMatrix.Column(j).ToArray();

                    if (Array.TrueForAll(nextCol, x => x == 0.0))
                    {
                        string s = "There is a column with all zeros. " +
                                   "That should not happen since the first row is " +
                                   "supposed to have no zeros.";
                        throw new ApplicationException(s);
                    }
                }

                if (throwAway)
                {
                    ++numThrows;
                }
            } while (throwAway);

            Console.WriteLine("RES_CONS_PAT: {0} Throw aways\n", numThrows);

            return(outputMatrix);
        }