Умножение матрицы на вектор

При умножении матрицы на вектор возможны два варианта:

  • умножение на вектор-столбец;
  • умножение на вектор-строку.

Чтобы найти произведение матрицы и вектора, необходимо умножать по правилу «строка на столбец»:

  • если умножить матрицу на вектор-столбец число столбцов в матрице должно совпадать с количеством элементов в векторе-столбце;
  • результатом умножения вектора-столбца является только вектор-столбец:
  • если умножить матрицу на вектор-строку, то умножаемая матрица должна быть исключительно вектором-столбцом, причем количество столбцов должно совпадать с количеством элементов в векторе-строке:

Реализация алгоритма

using System;

// класс с методами расширения
static class Ext
{
    // метод расширения для получения количества строк матрицы
    public static int RowsCount(this double[,] matrix)
    {
        return matrix.GetUpperBound(0) + 1;
    }

    // метод расширения для получения количества столбцов матрицы
    public static int ColumnsCount(this double[,] matrix)
    {
        return matrix.GetUpperBound(1) + 1;
    }

    // метод для печати матрицы в консоль
    public static void Print(this double[,] matrix)
    {
        for (var i = 0; i < matrix.RowsCount(); i++)
        {
            for (var j = 0; j < matrix.ColumnsCount(); j++)
            {
                Console.Write(matrix[i, j].ToString().PadLeft(4));
            }

            Console.WriteLine();
        }
    }

    // метод для печати вектора в консоль
    public static void Print(this double[] vector, bool vectorIsRow)
    {
        for (var i = 0; i < vector.Length; i++)
        {
            Console.Write(vector[i].ToString().PadLeft(4) + (vectorIsRow ? string.Empty: "\r\n" ));
        }
        Console.WriteLine();
    }
}

class Program
{
    // метод для получения вектора из консоли
    static double[] GetVectorFromConsole(string vectorName) 
    {
        Console.Write("Количество элементов вектора {0}:    ", vectorName);
        var n = int.Parse(Console.ReadLine());
        var vector = new double[n];
        for(var i = 0; i < vector.Length; i++)
        {
            Console.Write("{0}[{1}] = ", vectorName, i);
            vector[i] = double.Parse(Console.ReadLine());
        }
        
        return vector;
    }

    // метод для получения матрицы из консоли
    static double[,] GetMatrixFromConsole(string name)
    {
        Console.Write("Количество строк матрицы {0}:    ", name);
        var n = int.Parse(Console.ReadLine());
        Console.Write("Количество столбцов матрицы {0}: ", name);
        var m = int.Parse(Console.ReadLine());

        var matrix = new double[n, m];
        for (var i = 0; i < n; i++)
        {
            for (var j = 0; j < m; j++)
            {
                Console.Write("{0}[{1},{2}] = ", name, i, j);
                matrix[i, j] = double.Parse(Console.ReadLine());
            }
        }

        return matrix;
    }

    // метод для умножения матрицы на вектор
    static double[,] VectorMatrixMultiplication(double[,] inputMartix, double[] vector, bool vectorIsRow)
    {
        double[,] resultMatrix;
        if (vectorIsRow)
        {
            if (inputMartix.ColumnsCount() != 1)
            {
                throw new Exception("Умножение не возможно! Матрица должна содержать один столбец.");
            }
            if (inputMartix.RowsCount() != vector.Length)
            {
                throw new Exception("Умножение не возможно! Количество строк матрицы должно совпадать с количеством элементов вектора.");
            }

            resultMatrix = new double[vector.Length, vector.Length];

            for (var i = 0; i < resultMatrix.RowsCount(); i++)
            {
                for (var j = 0; j < resultMatrix.ColumnsCount(); j++)
                {
                    resultMatrix[i, j] = inputMartix[i, 0] * vector[j];
                }
            }
        }
        else
        {
            if (inputMartix.ColumnsCount() != vector.Length)
            {
                throw new Exception("Умножение не возможно! Количество столбцов матрицы должно совпадать с количеством элементов вектора.");
            }

            resultMatrix = new double[inputMartix.RowsCount(), 1];

            for (var i = 0; i < inputMartix.RowsCount(); i++)
            {
                resultMatrix[i, 0] = 0;

                for (var k = 0; k < inputMartix.ColumnsCount(); k++)
                {
                    resultMatrix[i, 0] += inputMartix[i, k] * vector[k];
                }
            }
        }

        return resultMatrix;
    }

    static void Main(string[] args)
    {
        Console.OutputEncoding = System.Text.Encoding.UTF8;
        Console.WriteLine("Программа для умножения матрицы на вектор");

        var m = GetMatrixFromConsole("M");
        var v = GetVectorFromConsole("V");

        Console.WriteLine("Вектор является строкой(R) или столбцом(C):");
        bool vectorIsRow = Console.ReadLine().ToUpper() == "R";

        Console.WriteLine("Матрица M:");
        m.Print();

        Console.WriteLine("Вектор V:");
        v.Print(vectorIsRow);

        var result = VectorMatrixMultiplication(m, v, vectorIsRow);
        Console.WriteLine("Произведение матрицы M на вектор V:");
        result.Print();

        Console.ReadLine();
    }
}

Смотрите также: