Search code examples
c#numerical-methods

Method inside a class, passes "this" as reference and not its value


I am trying to transform a 2-dimensional Matrix into its triangular representation using QR decomposition and Givens-Rotations. However, when I try passing the values of an object of my class Matrixx, it somehow passes its position in the memory, leading to changes in the original matrix when transforming the new one. I know that the following code is highly unefficient and chaotic, but first I wanna get it working before I try anything else.

public Matrixx MakeTriangular()
    {
        var watch = System.Diagnostics.Stopwatch.StartNew();
        int lines = this.DimI - 1;
        int dimj = this.DimJ;
        double r, s, c;
        Matrixx matrix = new Matrixx(this.DimI, this.DimJ);
        //  instead of 
        //  matrix = this; (which i would like to do)
        //  i have to pass each value seperately
        for (int x = 0; x < DimI; x++)
        {
            for (int y = 0; y < DimJ; y++)
            {
                matrix[x, y] = this[x, y];
            }
        } 
        for (int i = 1; i < lines + 1; i++) // i-te Zeile
        {
            for (int k = 0; k <= i - 1; k++) //k-te Spalte
            {
                if (Math.Abs(matrix[i,k]) > 0.000000001)
                {
                    for (int q = 0; q < DimI; q++)
                    {
                        for (int w = 0; w < DimJ; w++)
                        {
                            this[q, w] = matrix[q, w];
                        }
                    }
                    //Erstellen der Gik-Matrix
                    var Gik = new double[DimJ, DimJ];
                    r = Math.Sqrt(Math.Pow(this[k, k], 2) + Math.Pow(this[i, k], 2));
                    c = this[k, k] / r;
                    s = this[i, k] / r;
                    for (int tempi = 0; tempi < DimJ; tempi++)
                    {
                        for (int tempj = 0; tempj < DimJ; tempj++)
                        {
                            if (tempi == tempj)
                            { Gik[tempi, tempj] = 1; }
                            else
                            { Gik[tempi, tempj] = 0; }
                        }
                    }// Gik = Einheitsmatrix
                    for (int j = 0; j <= DimJ; j++)
                    {
                        for (int l = 0; l <= DimJ; l++)
                        {
                            if (j == i & l == i) Gik[j, l] = c;
                            if (j == k & l == k) Gik[j, l] = c;
                            if (j == k & l == i) Gik[j, l] = s;
                            if (j == i & l == k) Gik[j, l] = -s;
                        }
                    }// Ersetzen der Elemente [i,i], [i,k], [k,i] und [k,k]
                    for (int m = 0; m < DimI; m++)
                    {
                        for (int n = 0; n < DimJ; n++)
                        {
                            double temp = 0;
                            for (int o = 0; o < DimI; o++)
                            {
                                temp += Gik[m, o] * this[o, n];
                            }
                            matrix[m, n] = temp;
                        }
                    }
                }
            }
        }
        return matrix;
    }

Solution

  • fixed the issue by making the code shorter and moving the method from my class Matrixx to my main form, where i need it.

    private static Matrixx Triangularize(Matrixx A)
        {
            var result = A;
            for (var i = 1; i < A.DimI; i++)
            {
                for (var k = 0; k <= i - 1; k++)
                {
                    if (!(Math.Abs(result[i, k]) > 0.000000001)) continue;
                    var gik = new Matrixx(A.DimJ, A.DimJ);
                    var r = Math.Sqrt(Math.Pow(result[k, k], 2) + Math.Pow(result[i, k], 2));
                    var c = result[k, k] / r;
                    var s = result[i, k] / r;
                    for (var z = 0; z < A.DimJ; z++)
                    {
                        gik[z, z] = 1;
                        for (var y = 0; y < A.DimJ; y++)
                        {
                            if (z == i & y == i) gik[z, y] = c;
                            if (z == k & y == k) gik[z, y] = c;
                            if (z == k & y == i) gik[z, y] = s;
                            if (z == i & y == k) gik[z, y] = -s;
                        }
                    }
                    result = Multiplication(gik, result);
                }
            }
            return result;
    

    EDIT: any optimization suggestions are very welcome!