示例#1
0
                /// <summary>Matrix multiplication</summary>
                /// <param name="M1">Matrix 1</param>
                /// <param name="M2">Matrix 2</param>
                public double[,] MatrixMultiply(double[,] M1, double[,] M2)
                {
                    //M pxq, N qxr
                    int p = M1.GetLength(0);
                    int q = M1.GetLength(1);
                    int r = M2.GetLength(1);

                    if (q != M2.GetLength(0)) throw new Exception("Matrix dimensions do not match for multiplication");

                    double[] vecM1 = MatrixToVector(M1, ref p, ref q);
                    double[] vecM2 = MatrixToVector(M2, ref q, ref r);
                    double[] vecResp = new double[p * r];

                    CLCalc.Program.Variable varResp = new Program.Variable(vecResp);

                    CLCalc.Program.Variable varM1 = new Program.Variable(vecM1);
                    CLCalc.Program.Variable varM2 = new Program.Variable(vecM2);

                    //Finaliza a soma dos elementos
                    int[] vecQ = new int[1] { q };
                    CLCalc.Program.Variable varQ = new Program.Variable(vecQ);
                    CLCalc.Program.Variable[] args = new Program.Variable[4] { varResp, varM1, varM2, varQ };
                    int[] max = new int[2] { p, r };
                    doubleMatrixMult.Execute(args, max);

                    varResp.ReadFromDeviceTo(vecResp);

                    varResp.Dispose();

                    return VectorToMatrix(vecResp, ref p, ref r);
                }
示例#2
0
                /// <summary>Gauss Seidel method for iterative linear system solving. Returns unknown x</summary>
                /// <param name="M">Matrix M so that Mx=b</param>
                /// <param name="x">Initial estimate</param>
                /// <param name="b">Known vector b</param>
                /// <param name="Iterations">Gauss-Seidel iterations per step</param>
                /// <param name="MaxIter">Maximum number of times Gauss-Seidel iterations</param>
                /// <param name="totalError">Desired sqrt(Sum(error[i]^2))*number of equations</param>
                /// <param name="err">Estimated absolute error per component</param>
                public double[] LeastSquaresGS(double[,] M, double[] b, double[] x, int Iterations, int MaxIter, double totalError, out double[] err)
                {
                    //M pxp
                    int p = M.GetLength(0);
                    int q = M.GetLength(1);
                    //Consistencia
                    if (p != b.Length) throw new Exception("Matrix and vector b dimensions not compatible");
                    if (q != x.Length) throw new Exception("Matrix and initial guess x dimensions not compatible");

                    double[] vecM = MatrixToVector(M, ref p, ref q);
                    //Calculo de MtM e Mtb
                    CLCalc.Program.Variable varMtM = new Program.Variable(new double[q * q]);
                    CLCalc.Program.Variable varMtb = new Program.Variable(new double[q]);

                    {
                        CLCalc.Program.Variable varM = new Program.Variable(vecM);
                        CLCalc.Program.Variable varb = new Program.Variable(b);
                        CLCalc.Program.Variable varp = new Program.Variable(new int[1] { p });

                        CLCalc.Program.Variable[] arg = new Program.Variable[] { varM, varMtM, varp };
                        int[] maxs = new int[2] { q, q };
                        doubleCalcMtM.Execute(arg, maxs);

                        arg = new Program.Variable[] { varM, varb, varMtb, varp };
                        maxs = new int[1] { q };
                        doubleCalcMtb.Execute(arg, maxs);

                        varM.Dispose(); varb.Dispose(); varp.Dispose();
                    }

                    //Solucao do sistema
                    CLCalc.Program.Variable varx = new Program.Variable(x);
                    CLCalc.Program.Variable varerrx = new Program.Variable(x);
                    CLCalc.Program.Variable[] args = new Program.Variable[3] { varMtM, varMtb, varx };
                    CLCalc.Program.Variable[] args2 = new Program.Variable[4] { varMtM, varMtb, varerrx, varx };

                    int[] max = new int[1] { q };

                    double[] resp = new double[q];
                    err = new double[q];
                    double absErr = totalError + 1;
                    int i = 0;
                    while (i < MaxIter && absErr > totalError * (double)q)
                    //while (i < MaxIter && absErr > totalError)
                    {
                        for (int j = 0; j < Iterations; j++)
                        {
                            doubleGaussSeidel.Execute(args, max);
                            i++;
                        }
                        //Calcula o erro
                        doubleGaussSeidelError.Execute(args2, max);
                        varerrx.ReadFromDeviceTo(err);

                        absErr = 0;
                        for (int j = 0; j < q; j++) absErr += err[j] * err[j];
                        absErr = (double)Math.Sqrt(absErr);
                    }

                    //Retorna a resposta
                    varx.ReadFromDeviceTo(resp);
                    varerrx.ReadFromDeviceTo(err);

                    //Limpa memoria
                    varMtM.Dispose(); varx.Dispose(); varerrx.Dispose(); varMtb.Dispose();

                    return resp;
                }