Ну, вектор нормальный данному единичному построить можно проще - достаточно заменить любую его координату xi на -sqrt(1-xi^2). Это фактически эквивалентно повороту на 90 градусов в полскости вектора в сторону от i-й оси (т.е. косинус заменяем на -синус, получаем косинус угла+пи/2). После этого остается только нормировать результат.
Но не факт, что таким образом вообще можно получить вектор, нормальный всем остальным из набора. Как и любым другим способом, выбирающим один нормальный вектор из всех вариантов...
Ну, вектор нормальный данному единичному построить можно проще - достаточно заменить любую его координату xi на -sqrt(1-xi^2). Это фактически эквивалентно повороту на 90 градусов в полскости вектора в сторону от i-й оси (т.е. косинус заменяем на -синус, получаем косинус угла+пи/2). После этого остается только нормировать результат.
Но не факт, что таким образом вообще можно получить вектор, нормальный всем остальным из набора. Как и любым другим способом, выбирающим один нормальный вектор из всех вариантов...
Именно. В общем случае не так.
--
Похоже я нашёл шустрое решение. Когда сел писать и расслабился на тему алгоритма - само всплыло.
Вопчем, нужно из сгенерированного вектора x1r, просто вычесть его проекцию на x0 (т.е. x0*sp(x0,x1r), где sp() - скалярное произведение).
Короче формула в одну строчку: x1 = x1r - x0*sp(x0,x1r);
На плоской картинке всё вроде получается. Мне кажется, что и для N-мерного случая будет работать. Есть возражения?
Пора, похоже, скрипт написать, да проверить... :)
Можно не писать. Доказательство:
sX = (a1+b1,a2+b2); dX = (a1-b1,a2-b2);
Поскольку векторы a и b были единичными, то соответствующий параллелограмм является ромбом и его диагонали перпендикулярны, значит сумма и разность ортогональны друг другу. Следовательно, обмен модулями эквивалентен повороту одного из них на 90 градусов вправо и другого - влево. В декартовых координатах можем выразить это просто перестановкой местами первой и второй координат:
sXtr = (a2-b2,a1-b1); dXtr = (a2+b2,a1+b1)
=>
sXtr+dXtr = (2*a2,2*a1) - вектор с модулем 2 и, очевидно, ортогональный вектору (a1,a2), то есть вектору a. Ч.т.д.
MetaDriver: Осталось в цикле запустить. for(i=0; i<InpVectorCount; i++) {....}
Не, все равно все сводится к тому, чтобы изначально выбрать правильный "произволный" вектор, который даст в итоге ортогогональность всему набору. Т.е. произвольный получается совсем даже и не произвольный. Снова возвращаемся к тому, как рассчитать нужный начальный вектор.
alsu: Не, все равно все сводится к тому, чтобы изначально выбрать правильный "произволный" вектор, который даст в итоге ортогогональность всему набору. Т.е. произвольный получается совсем даже и не произвольный. Снова возвращаемся к тому, как рассчитать нужный начальный вектор.
Фигня. Просто проверки на каждом шаге. Если на каком либо шаги трансформации вектор становится сонаправленным следующему в наборе - генерим начальный случайный вектор заново и повторяем процедуру. Поскольку случай этот маловероятен (при конечной размерности), то это проще (дешевле), чем сразу же подозревать его на линейную зависимость (искать ранг матрицы).
MetaDriver: Фигня. Просто проверки на каждом шаге. Если на каком либо шаги трансформации вектор становится сонаправленным следующему в наборе - генерим начальный случайный вектор заново и повторяем процедуру. Поскольку случай этот маловероятен (при конечной размерности), то это проще (дешевле), чем сразу же подозревать его на линейную зависимость (искать ранг матрицы).
Он может стать не сонаправленным, а просто под непрямым углом ко всем или некоторым векторам
MetaDriver: Фигня. Просто проверки на каждом шаге. Если на каком либо шаги трансформации вектор становится сонаправленным следующему в наборе - генерим начальный случайный вектор заново и повторяем процедуру. Поскольку случай этот маловероятен (при конечной размерности), то это проще (дешевле), чем сразу же подозревать его на линейную зависимость (искать ранг матрицы).
А дешевле это потому, что скалярное произведение всё равно придётся вычислять (по алгоритму). Вот если оно окажется равным единице - сбрасываемся в начало и повторяем процесс. Т.е. на каждом шаге просто проверка if(cp(a,b)! = 1.0) {}
Для авторизации и пользования сайтом MQL5.com необходимо разрешить использование файлов Сookie.
Пожалуйста, включите в вашем браузере данную настройку, иначе вы не сможете авторизоваться.
Вы вошли в аккаунт. Двухфакторная аутентификация отключена. Настройте её заново и отсканируйте новый QR-код или продолжите с отключённой двухфакторной аутентификацией.
На плоской картинке всё вроде получается. Мне кажется, что и для N-мерного случая будет работать. Есть возражения?
Пора, похоже, скрипт написать, да проверить... :)
Ну, вектор нормальный данному единичному построить можно проще - достаточно заменить любую его координату xi на -sqrt(1-xi^2). Это фактически эквивалентно повороту на 90 градусов в полскости вектора в сторону от i-й оси (т.е. косинус заменяем на -синус, получаем косинус угла+пи/2). После этого остается только нормировать результат.
Но не факт, что таким образом вообще можно получить вектор, нормальный всем остальным из набора. Как и любым другим способом, выбирающим один нормальный вектор из всех вариантов...
Ну, вектор нормальный данному единичному построить можно проще - достаточно заменить любую его координату xi на -sqrt(1-xi^2). Это фактически эквивалентно повороту на 90 градусов в полскости вектора в сторону от i-й оси (т.е. косинус заменяем на -синус, получаем косинус угла+пи/2). После этого остается только нормировать результат.
Но не факт, что таким образом вообще можно получить вектор, нормальный всем остальным из набора. Как и любым другим способом, выбирающим один нормальный вектор из всех вариантов...
Именно. В общем случае не так.
--
Похоже я нашёл шустрое решение. Когда сел писать и расслабился на тему алгоритма - само всплыло.
Вопчем, нужно из сгенерированного вектора x1r, просто вычесть его проекцию на x0 (т.е. x0*sp(x0,x1r), где sp() - скалярное произведение).
Короче формула в одну строчку: x1 = x1r - x0*sp(x0,x1r);
:))
:))
Ага. Только ещё отнормировать после этого.
Ну всё равно в одну строчку: x1 = norm(x1r - x0*sp(x0,x1r));
На плоской картинке всё вроде получается. Мне кажется, что и для N-мерного случая будет работать. Есть возражения?
Пора, похоже, скрипт написать, да проверить... :)
Можно не писать. Доказательство:
sX = (a1+b1,a2+b2); dX = (a1-b1,a2-b2);
Поскольку векторы a и b были единичными, то соответствующий параллелограмм является ромбом и его диагонали перпендикулярны, значит сумма и разность ортогональны друг другу. Следовательно, обмен модулями эквивалентен повороту одного из них на 90 градусов вправо и другого - влево. В декартовых координатах можем выразить это просто перестановкой местами первой и второй координат:
sXtr = (a2-b2,a1-b1); dXtr = (a2+b2,a1+b1)
=>
sXtr+dXtr = (2*a2,2*a1) - вектор с модулем 2 и, очевидно, ортогональный вектору (a1,a2), то есть вектору a. Ч.т.д.
Осталось в цикле запустить. for(i=0; i<InpVectorCount; i++) {....}
Не, все равно все сводится к тому, чтобы изначально выбрать правильный "произволный" вектор, который даст в итоге ортогогональность всему набору. Т.е. произвольный получается совсем даже и не произвольный. Снова возвращаемся к тому, как рассчитать нужный начальный вектор.
Фигня. Просто проверки на каждом шаге. Если на каком либо шаги трансформации вектор становится сонаправленным следующему в наборе - генерим начальный случайный вектор заново и повторяем процедуру. Поскольку случай этот маловероятен (при конечной размерности), то это проще (дешевле), чем сразу же подозревать его на линейную зависимость (искать ранг матрицы).
Фигня. Просто проверки на каждом шаге. Если на каком либо шаги трансформации вектор становится сонаправленным следующему в наборе - генерим начальный случайный вектор заново и повторяем процедуру. Поскольку случай этот маловероятен (при конечной размерности), то это проще (дешевле), чем сразу же подозревать его на линейную зависимость (искать ранг матрицы).