Наименьший квадрат на линейной N-ходовой задаче - PullRequest
0 голосов
/ 26 декабря 2018

Предположим, я хочу найти «точку пересечения» двух произвольных многомерных линий.Две линии на самом деле не будут пересекаться , но я все же хочу найти самую точку пересечения (т. Е. Точку, максимально приближенную ко всем линиям).

Предположим, что эти линии имеют векторы направления A, B и начальные точки C, D. Я могу найти самую точку пересечения, просто установив линейную задачу наименьших квадратов: преобразование линииуравнение пересечения

Ax + C = By + D

в форму наименьших квадратов

[A, -B] @ [[x, y]] = D - C 

, где @ стандарты для вектора времени матрицы, и затем я могу использовать, например, np.linalg.lstsq для его решения.

Но как мне найти «самую пересекающуюся точку» из 3 или более произвольных линий?Если я буду следовать тому же правилу, у меня теперь будет

Ax + D = By + E = Cz + F

Единственный способ, которым я могу думать, это разложить это на три уравнения:

Ax + D = By + E
Ax + D = Cz + F
By + E = Cz + F

и преобразовать их в форму наименьших квадратов

[A, -B,  0]                 [E - D]
[A,  0, -C] @ [[x, y, z]] = [F - D]
[0,  B, -C]                 [F - E]

Проблема в том, что размер задачи наименьших квадратов увеличивается квадратично по отношению к числу строк.Мне интересно, есть ли более эффективный способ решения линейной задачи наименьших квадратов, равной n-путям ?

Я думал о необходимости By + E = Cz + F выше, предоставляя два других термина,Но поскольку эта проблема не имеет точного решения (то есть они фактически не пересекаются), я считаю, что это создаст больший «вес» для некоторой переменной?

Спасибо за вашу помощь!

РЕДАКТИРОВАТЬ

Я только что проверил соединение первого члена со всеми другими членами в n-way-равенства (и без других пар), используя следующий код

def lineIntersect(k, b):
    "k, b: N-by-D matrices describing N D-dimensional lines: k[i] * x + b[i]"

    # Convert the problem to least-square form `Ax = B`
    # A is temporarily defined 3-dimensional for convenience
    A = np.zeros((len(k)-1, k.shape[1], len(k)), k.dtype)
    A[:,:,0] = k[0]
    A[range(len(k)-1),:,range(1,len(k))] = -k[1:]

    # Convert to 2-dimensional matrix by flattening first two dimensions
    A = A.reshape(-1, len(k))

    # B should be 1-dimensional vector
    B = (b[1:] - b[0]).ravel()

    x = np.linalg.lstsq(A, B, None)[0]

    return (x[:,None] * k + b).mean(0)

Приведенный ниже результат показывает, что неверно , потому что первый член в n-way-равенства "взвешен по-другому".

Первый вывод - это разница между обычным результатом и результатом различного порядка ввода (порядок строк не имеет значения), где первый член не изменился .

второй вывод совпадает с первый член изменился .

k = np.random.rand(10, 100)
b = np.random.rand(10, 100)
print(np.linalg.norm(lineIntersect(k, b) - lineIntersect(np.r_[k[:1],k[:0:-1]], np.r_[b[:1],b[:0:-1]])))
print(np.linalg.norm(lineIntersect(k, b) - lineIntersect(k[::-1], b[::-1])))

приводит к

7.889616961715915e-16
0.10702479853076755

Ответы [ 4 ]

0 голосов
/ 27 декабря 2018

Другим критерием для «точки почти пересечения» была бы точка x, такая, что сумма квадратов расстояний x до линий будет как можно меньше.Как и ваш критерий, если линии действительно пересекаются, то точка пересечения будет практически точкой пересечения.Тем не менее, я думаю, что критерий суммы квадратов расстояний упрощает вычисление рассматриваемой точки:

Предположим, мы представляем линию точкой и единичный вектор вдоль линии.Таким образом, если линия представлена ​​p, t, то точки на линии имеют вид

p + l*t for scalar l

Квадрат расстояния точки x от линии p, t равен

(x-p)'*(x-p) - square( t'*(x-p))

Если у нас есть N линий p [i], t [i], то сумма квадратов расстояний от точки x равна

   Sum { (x-p[i])'*(x-p[i]) - square( t[i]'*(x[i]-p[i]))}

Расширяя это, я получаю вышеприведенное значение

x'*S*x - 2*x'*V + K

, где

S = N*I - Sum{ t[i]*t[i]'}
V = Sum{ p[i] - (t[i]'*p[i])*t[i] }

и K не зависит от x

Если все линии не параллельны, S будет (строго) положительно определенным и, следовательно, обратимым, и вв этом случае наша сумма квадратов расстояний равна

(x-inv(S)*V)'*S*(x-inv(S)*V) + K - V'*inv(S)*V

Таким образом, минимизирующий x равен

inv(S)*V

Итак, упражнение: нормализуйте ваши «векторы направления» (и масштабируйте каждую точку к тому жекоэффициент, используемый для масштабирования направления), сформируйте S и V, как указано выше, решите

S*x = V for x
0 голосов
/ 26 декабря 2018

Этот вопрос может лучше подойти для обмена стека математики.Кроме того, у кого-нибудь есть хороший способ форматирования математики здесь?Извините, что это трудно читать, я сделал все возможное с Unicode.

РЕДАКТИРОВАТЬ: я неправильно истолковал, что @ ZisIsNotZis означает строки Ax+C, так что игнорировать следующий абзац.

Я не уверен, что ваш метод изложен правильно.Не могли бы вы опубликовать свой код и небольшой пример вывода (возможно, в 2d с 3 или 4 строками, чтобы мы могли построить его)?Когда вы пытаетесь найти пересечение двух линий, разве вы не должны Ax+C = Bx+D?Если вы сделаете Ax+C=By+D, вы можете выбрать несколько x в первой строке и несколько y во второй строке и точно удовлетворить оба уравнения.Потому что здесь x и y должны быть того же размера, что и A и B, что является измерением пространства, а не скаляров.

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

Предположим, у нас есть строка в R^n: c^Tz + d = 0 (где c - длина единицы) идругая точка x.Тогда самый короткий вектор от x до линии: (I-cc^T)(x-d), поэтому квадрат расстояния от x до линии ║(I-cc^T)(x-d)║^2.Мы можем найти самую близкую точку к линии, минимизируя это расстояние.Обратите внимание, что это стандартная задача наименьших квадратов в форме min_x ║b-Ax║_2.

Теперь предположим, что у нас есть строки, заданные c_iz+d_i для i=1,...,m.Квадратное расстояние d_i^2 от точки x до i -ой линии равно d_i^2 = ║(I-cc^T)(x-d)║_2^2.Теперь мы хотим решить проблему min_x \sum_{i=1}^{m} d_i^2.

В матричной форме мы имеем:

      ║ ⎡ (I-c_1 c_1^T)(x-d_1) ⎤ ║
      ║ | (I-c_2 c_2^T)(x-d_2) | ║
min_x ║ |      ...             | ║
      ║ ⎣ (I-c_n c_n^T)(x-d_n) ⎦ ║_2

Это снова в форме min_x ║b - Ax║_2, поэтому есть хорошие решатели.

Каждый блок имеет размер n (размерность пространства) и m блоков (количество строк).Таким образом, система mn по n.В частности, оно линейно по количеству линий и квадратично по размерности пространства.

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

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

0 голосов
/ 26 декабря 2018

Вы говорите, что у вас есть две "многомерные" линии.Это означает, что матрица, указывающая на строки, имеет намного больше столбцов, чем строк.

Если это так, и вы можете эффективно найти разложение низкого ранга, такое, что A = LRᵀ , тогда выможно переписать решение задачи наименьших квадратов min || Ax-y || ₂ как x = (Rᵀ RLᵀ L) ⁻¹ Lᵀ y .

Если m - это число линий, а n - размерность линий, тогда это уменьшает временную сложность наименьших квадратов с O (mn² + nʷ) до O (nr² + mr²) где r = min (m, n) .

Задача состоит в том, чтобы найти такое разложение.

0 голосов
/ 26 декабря 2018

Не решение, некоторые мысли:

Если линия в nD-пространстве имеет параметрическое уравнение (с единицей Dir вектор)

 L(t) = Base + Dir * t

, то возводится в квадрат расстояние от точки P доэта строка равна

W = P - Base
Dist^2 = (W - (W.dot.Dir) * Dir)^2

Если возможно записать Min(Sum(Dist[i]^2)) в форме, подходящей для метода LSQ (сделать частные производные по каждой точке координат), то полученная система может быть решена для (x1..xn) вектора координат.

(Ситуация напоминает разворот многих точек и одной линии обычного LSQ)

...