Проверить собственные пары


21

В этом задании вам дадут квадратную матрицу A, вектор vи скаляр λ. Вам необходимо будет определить, соответствует ли (λ, v)собственная пара A; то есть, или нет Av = λv.

Скалярное произведение

Точечное произведение двух векторов является суммой поэлементного умножения. Например, скалярное произведение следующих двух векторов:

(1, 2, 3) * (4, 5, 6) = 1*4 + 2*5 + 3*6 = 32

Обратите внимание, что скалярное произведение определяется только между двумя векторами одинаковой длины.

Матрично-векторное умножение

Матрица - это двумерная сетка значений. Матрица mх nимеет mстроки и nстолбцы. Мы можем представить матрицу mx nкак mвекторы длины n(если взять строки).

Умножение матрицы на вектор определяется между матрицей mx nи nвектором размера . Если мы умножим матрицу mx nна nвектор размеров , мы получим mвектор размеров . Значение i-th в векторе результатов является точечным произведением i-ой строки матрицы и исходного вектора.

пример

        1 2 3 4 5
Let A = 3 4 5 6 7
        5 6 7 8 9

        1
        3
Let v = 5
        7
        9

Если мы умножим матрицу и вектор Av = x, мы получим следующее:

x 1 = A T 1 * v /* AT1 means the first row of A; A1 would be the first column */= (1,2,3,4,5) * (1,3,5,7,9) = 1 * 1 + 2 * 3 + 3 * 5 + 4 * 7 + 5 * 9 = 1 + 6 + 15 + 28 + 45 = 95

x 2 = A T 2 * v = (3,4,5,6,7) * (1,3,5,7,9) = 3 * 1 + 4 * 3 + 5 * 5 + 6 * 7 + 7 * 9 = 3 + 12 + 25 + 42 + 63 = 145

x 3 = A T 3 * v = (5,6,7,8,9) * (1,3,5,7,9) = 5 * 1 + 6 * 3 + 7 * 5 + 8 * 7 + 9 * 9 = 5 + 18 + 35 + 56 + 81 = 195

Итак, мы получаем Av = x = (95, 145, 195).

Скалярное Умножение

Умножение скаляра (одного числа) и вектора - просто поэлементное умножение. Например, 3 * (1, 2, 3) = (3, 6, 9). Это довольно просто.

Собственные значения и собственные векторы

Учитывая матрицу A, мы говорим, что λявляется собственным значением, соответствующим vи vявляется собственным вектором, соответствующим λ тогда и только тогда, когда Av = λv . (Где Avматрично-векторное умножение и λvскалярное умножение).

(λ, v) это собственная пара.

Технические требования

вход

Входные данные будут состоять из матрицы, вектора и скаляра. Они могут быть приняты в любом порядке в любом разумном формате.

Выход

Вывод будет истинным / ложным значением; правда тогда и только тогда, когда скаляр и вектор являются собственной парой с указанной матрицей.

правила

  • Применяются стандартные лазейки
  • Если на вашем языке существует встроенная система проверки собственной пары, вы не можете ее использовать.
  • Вы можете предположить, что все числа являются целыми числами

Тестовые случаи

 MATRIX  VECTOR  EIGENVALUE
 2 -3 -1    3
 1 -2 -1    1    1    ->    TRUE
 1 -3  0    0

 2 -3 -1    1
 1 -2 -1    1    -2   ->    TRUE
 1 -3  0    1

 1  6  3    1
 0 -2  0    0    4    ->    TRUE
 3  6  1    1

 1  0 -1    2
-1  1  1    1    7    ->    FALSE
 1  0  0    0

-4 3    1    
 2 1    2    2    ->    TRUE

2    1    2    ->    TRUE

Я добавлю 4x4 позже.

Нечитаемые тестовые случаи, которые легче тестировать



@MartinEnder Спасибо. Изначально у меня была похожая проблема для матриц произвольного размера, где вы должны были рассчитать базис для каждого уникального собственного пространства, но это все еще в песочнице, потому что это кажется слишком запутанным.
HyperNeutrino

Если входные данные могут иметь размеры, отличные от 3x3, некоторые из них следует учитывать в ваших тестовых примерах.
Мартин Эндер

1
@HyperNeutrino да, это не помогает ... Не пытайтесь объяснить это мне: я учусь в средней школе по математике для GCSE, так что это просто потеряно для меня.
caird coinheringaahing

1
@ user00001 Если вам нужна помощь, eigenpair-перефразировать ее для вас. : P
mbomb007

Ответы:


11

Желе , 5 байт

æ.⁵⁼×

Это триада, полная программа.

Попробуйте онлайн!

Как это устроено

æ.⁵⁼×  Main link
       Left argument:  v (eigenvector)
       Right argument: λ (eigenvalue)
       Third argument: A (matrix)

  ⁵    Third; yield A.
æ.     Take the dot product of v and A, yielding Av.
    ×  Multiply v and λ component by component, yielding λv.
   ⁼   Test the results to the left and to the right for equality.

> _> это слишком коротко: P Хороший ответ
HyperNeutrino

6
Это безумный разговор! : P
Деннис

Вы пишете что-то и думаете: «Ничто не может быть короче!». Затем прибывает MATL и уменьшает ваш код вдвое. Затем приходит Jelly и
делит

@HyperNeutrino Не сравнивайте яблоки с апельсинами. Языки игры в гольф имеют всего один байт на операцию, что обычно бывает в обычных языках. Спецификация имеет три операции (два умножения и равенство), и для дублирования дополнительного байта vможно ожидать всего четыре байта.
Sanchises

2
Мне нравится, как Jelly и MATL используют два байта для умножения матриц, что означает, что этот ответ действительно показывает, насколько хорошо Jelly принимает входные данные, при прочих равных условиях.
Sanchises

13

Mathematica, 10 байт

#2.#==#3#&

Принимает ввод как {vector, matrix, scalar}и возвращает логическое значение.


1
> _> Это было слишком просто для Mathematica. +1: P
HyperNeutrino

9
@HyperNeutrino А теперь мы ждем MATL ...
Мартин Эндер,

2
Ну вот МАТЛ появился> _>
HyperNeutrino

1
Один из тех моментов, когда вы думаете, что ничто не может быть короче, и MATL неожиданно появляется :)
Mr. Xcoder

@ Mr.Xcoder А потом появляется Джелли.
Steadybox

11

MATL, 7 байт

*i2GY*=

Входы в порядке: l, v, A.

Объяснение:

*  % implicitly get l and v, multiply.
i  % get A
2G % get second input, i.e., v again
Y* % perform matrix multiplication
=  % test equality of both multiplications

Удивительно длинный ответ, если вы спросите меня, в основном потому, что мне нужен был способ, чтобы получить все данные правильно. Я не думаю, что возможно менее 5 байтов, но было бы здорово, если бы кто-то нашел 5 или 6 байтовое решение.

В основном, это рассчитывает l*v==A*v.


«Удивительно долго» я ​​ожидал как минимум 20 байтов> _> хороший ответ, хотя: P
HyperNeutrino

2
Что ж, учитывая, что ответ MATLAB должен быть в 16 байтах @(A,v,l)A*v==v*l, это кажется довольно многословным, и я чувствую, что 6 должно быть достаточно, если я получу ввод несколько умнее.
Sanchises

По-видимому, он был размером 38 байт, но я уверен, что его можно проиграть.
HyperNeutrino

3
@HyperNeutrino Добавил мой собственный, чтобы сделать предыдущий комментарий правдой. (или правда ...?)
Sanchises

6

CJam , 15 байтов

q~W$f.*::+@@f*=

Принимает участие в форме vector scalar matrix.

Попробуйте онлайн!

объяснение

q~               e# Read and eval the input
  W$             e# Copy the bottom most value (the vector)
    f.*::+       e# Perform element-wise multiplication with each row of the matrix, then
                 e#   sum the results of each (ie dot product with each row) 
          @@     e# Move the resulting vector to the bottom of the stack
            f*   e# Element-wise multiplication of the scalar and the vector
              =  e# Check if the two vectors are equal

5

MATLAB, 16 байтов

@(A,v,l)A*v==v*l

Скорее банальный ответ. Определяет анонимную функцию, принимающую входные данные, и вычисляет поэлементное равенство результирующих векторов. Один ноль в логическом массиве делает массив ложным в MATLAB.


Не знал о лжи, например [true,false], спасибо, что научил меня =)
flawr

1
@flawr Смотрите этот ответ от Suever (который также применим к MATLAB). В принципе, почти-но-не-совсем (пустая матрица []отличается) неявно all()вызывается на входе if, и whileт.д.
Sanchises

2

MATLAB, 38 байт

function r=f(m,v,s);r=isequal(m*v,s*v)

Возвращает 1 или 0.

MATLAB, 30 байтов

function r=f(m,v,s);r=m*v==s*v

Возвращает

1
1
1

как истинная ценность. Ложное значение - это аналогичный вектор с любыми или всеми значениями 0 вместо 1.


Я не знаю MATLAB, но можно isequalли сократить функцию до ==?
HyperNeutrino

1
@HyperNeutrino isequalбыли бы необходимы , если требуется выходной trueили , falseа не truthy или значение falsey. Поскольку проблема стоит, ==действительно достаточно.
Sanchises

@HyperNeutrino Возвращает вектор, содержащий результаты поэлементного сравнения двух векторов.
Steadybox

Ох, ну ладно. Хороший ответ, хотя!
HyperNeutrino

Разве анонимная функция не будет короче?
Бэтмен

2

C ++, 225 203 байта

Спасибо @Cort Ammon и @Julian Wolf за сохранение 22 байтов!

#import<vector>
#define F(v,i)for(i=0;i<v.size();++i)
using V=std::vector<float>;int f(std::vector<V>m,V v,float s){V p;int i,j;F(m,i){p.push_back(0);F(v,j)p[i]+=v[j]*m[i][j];}F(v,i)v[i]*=s;return v==p;}

Попробуйте онлайн!


1
using std::vector;может сыграть в гольф два байта от этого Это стоит 18 байт, но может удалить 4 std::с, сэкономив 20.
Cort Ammon - Восстановить Монику

2
еще лучше, using V=std::vector<float>;или подобное
Джулиан Вольф


2

Python 2.7, 33 байта

f=lambda m,s,e:all(m.dot(s)==e*s)

вход: m = матрица, s = скаляр, e = собственное значение. M и S являются массивами NumPy


2
Это выглядит хорошо, но я думаю, что вам нужно включить количество байтов, import npчтобы оно было действительным
DJMcMayhem

1
Ваше предыдущее print(m,s,e)заявление не будет работать , так как переменные m, sи eеще не были назначены / определенно. Также вы можете удалить пробел после двоеточия. Кроме того, вы можете удалить часть `as n` и использовать numpyпозже; так как вы используете его только один раз, полное имя сохраняет байт.
HyperNeutrino

1
Хорошо, сейчас я понимаю. Спасибо за предложения, сжимая каждый кусочек :)
HonzaB

2
Разве это не должно быть allвместо any? И я думаю, что sэто вектор, а не скаляр, если я что-то упустил
Луис Мендо

1
Было бы еще короче сравнить строковые представления. tio.run/nexus/python2#jZDPCoMwDIfP@hQ9tiOV/hEHgk/…
Деннис

2

Python 3 , 96 70 байт

Никаких встроенных функций для умножения матрицы на вектор или скалярного вектора!

lambda A,L,v:all(L*y==sum(i*j for i,j in zip(x,v))for x,y in zip(A,v))

Попробуйте онлайн!

-26 байт благодаря использованию zip@LeakyNun!




1

R, 30 25 байт

s=pryr::f(all(a%*%v==λ*v))

Анонимная функция, довольно простая. Возвращает TRUEили FALSE.


0

ОК, 12 байт

{y~z%+/y*+x}

Это функция, она принимает [matrix;vector;scalar].

Это не работает в к по тем же причинам , что 3.0~3дает 0в результате.


Следующие работы в k , с 14 байтами :

{(y*z)~+/y*+x}

0

Аксиома, 27 байт

f(a,b,c)==(a*b=c*b)@Boolean

упражнения

(17) -> m:=matrix[[2,-3,-1],[1,-2,-1],[1,-3,0] ]; v:=matrix[[3],[1],[0]];
(18) -> f(m,v,1)
   (18)  true

(19) -> m:=matrix[[2,-3,-1],[1,-2,-1],[1,-3,0] ]; v:=matrix[[1],[1],[1]];
(20) -> f(m,v,-2)
   (20)  true

(21) -> m:=matrix[[1,6,3],[0,-2,0],[3,6,1] ]; v:=matrix[[1],[0],[1]];
(22) -> f(m,v,4)
   (22)  true

(23) -> m:=matrix[[1,0,-1],[-1,1,1],[1,0,0] ]; v:=matrix[[2],[1],[0]];
(24) -> f(m,v,7)
   (24)  false

(25) -> m:=matrix[[-4,3],[2,1] ]; v:=matrix[[1],[2]];
(26) -> f(m,v,2)
   (26)  true

(27) -> f(2,1,2)
   (27)  true

Я не видел этот язык раньше, хороший ответ! Что делает @Boolean?
ГиперНейтрино

(a = b) @Boolean будет означать «выберите из допустимого оператора = (тип1, тип2) тот, результатом которого является логический»; в нескольких словах "a = b" должно быть логическим
РосЛюП

0

Python, 26 байт

lambda a,b,c:c*b==a.dot(b)

aи bявляются массивами numpy, cявляется целым числом.

Попробуйте онлайн!


2
Парни вокруг c*bдействительно необходимы?
xnor

@ xnor спасибо, исправлено.
Rɪᴋᴇʀ

Это работает только для небольших массивов, поскольку NumPy устраняет представления строк большого массива.
user2357112 поддерживает Monica

@ user2357112 пример? Я не уверен, что ты имеешь в виду.
Rɪᴋᴇʀ

Если c*bсодержит более 1000 элементов, NumPy заменит большинство элементов на .... Demo.
user2357112 поддерживает Monica

0

Clojure, 60 байт

#(=(set(map(fn[a v](apply -(* v %3)(map * a %2)))% %2))#{0})

Это проверяет, что все дельты равны нулю, таким образом, сводится к множеству нуля. Пример вызова:

(def f #(=(set(map(fn[a v](apply -(* v %3)(map * a %2)))% %2))#{0}))
(f [[1 6 3][0 -2 0][3 6 1]] [1 0 1] 4)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.