Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Не благодарите :-). Все будете делать сами :-).
Расписал по шагам:
.
#1 (тестовый, можно не делать ;-) :
В С++ создайте матрицу с числом строк MAX_ROW = 5..10, столбцов MAX_COL = 5..10 (числа случайным образом).
Сделайте случайное заполнение данными.
.
#2 (тестовый, можно не делать ;-) : решите следующую задачу:
Матрицу с шага #1 нужно представить в одномерном виде.
создайте одномерный массив double размера=MAX_ROW*MAX_COL, в котором данные хранятся по формуле
for(line = 0 .. MAX_COL-1)
for(column = 0 .. MAX_COL-1)
array[line*MAX_COL + column] = data[line][column];
.
#3: решите следующую задачу / в виде функции
Вам приходит одномерный массив double из шага (2), число строк и столбцов.
Вы должны данные из этого массива положить в объект ap::real_2d_array
.
#4: Вам приходит объект ap::real_2d_array / в виде функции
Вы должны преобразовать его в одномерный массив double, получить число строк и столбцов.
.
#5 (тестовый, можно не делать ;-) :
Одномерный массив Вы должны преобразовать в двумерную матрицу (как в шаге 1).
Полученную матрицу сравнить с исходной матрицей из шага 1.
В случае несовпадения- разбираться.
.
Главные функции, которые будут нужны- это функции 3 и 4.
Шаги 1,2 = тренировочные, Вам придется так запаковывать данные в Mql, шаг 5 = проверочный.
.
В общем-то, я сделал бы функции для каждого из 5-ти шагов.
.
Сингулярное преобразование на Mql.
https://www.mql5.com/ru/code/7359
Спасибо за подробный расклад как должен работать этот алгоритм сингулярного разложения. Пункты 1-3 у меня реализованы. Осталась проблема с пунктом 4, т.к. у меня пока не получается создать рабочую dll с экспортом функции rmatrixsvd(...), как я писал ранее,
из-за внесения в первоначальный код на С++: extern "C" bool __declspec(dllexport) __stdcall rmatrixsvd(...), начинаются ошибки... хотя, если компилировать просто bool rmatrixsvd(...), то ошибок нет... но мне то нужна экспортируемая функция... Вот здесь и ступор...
Спасибо за помощь.
Относительно пункта 4 (и всех остальных). rmatrixsvd к нему не имеет никакого отношения.
Равно как и алгоритм сингулярного разложения. Это пункты, относящиеся
к передаче-получению данных из/в Dll.
.
Прототип функции, которую нужно написать для п. 4:
void Convert_real_2d_array_to_double(
const ap::real_2d_array & arr,
double * data,
int & lines,
int & columns
);
.
Т.е. Вам нужно научиться доставать из ap::real_2d_array кол-во строк, столбцов и данные.
.
Из этого:
const ap::real_2d_array & arr
---->>>
получить это:
double * data,
int & lines,
int & columns
Спасибо огромное ещё раз, что уделяете мне время.
Ещё раз прочитал все записи очень внимательно и похоже наконец-то до меня дошло :-), что нужно делать.
Действительно, сама функция rmatrixsvd тут как бы является "рабочей лошадкой" и не надо пытаться её экспортировать,
а нужно всего лишь вовремя положить груз на телегу, а потом аккуратно его выгрузить в нужное место, когда оно будет доставлено
по назначению. если говорить образно. Я правильно сейчас Вас понял?
Т.е. мне надо на С++ сделать эти конверторы данных пункт 3 и 4 и по сути дела в MQL работать с ними, т.е. объявлять их в MQL, а в DLL они
должны объявляться как экспортируемые, чтобы Метатрейдер мог с ними работать. Я правильно понимаю суть своей проблемы?
Если это так, а мне кажется, что сейчас я Вас понял, то это даже ещё лучше, т.к. не знал как же потом увязать двумерные и одномерные массивы.
Тем более, что в MQL же нельзя объявлять массив как a[ ][ ]? Т.е. нужно хотя бы объявить как a[ ][100]. Это же так? или я ошибаюсь?
А это не очень удобно, т.к. заранее не знаешь какова будет размерность двумерного массива, а резервировать память под массив заранее, в прок - не лучший вариант,
а в С++ такой проблемы нет? т.е. двумерный массив может быть образно говоря "резиновый". Это так? Или в С++ тоже есть некие нюансы?
Ещё хотел узнать у Вас по поводу Borland Builder 2009. Может он не такой глючный как 6-ка? И в принципе на нём можно работать?
А то alsu вообще, как я понимаю, сказал, что он - дебилдер. :-) А Вы программируете, насколько я понял, на Visual Studio? Он круче? И без глюков? А какая сейчас последняя версия?
Я рад, что я понял суть своей проблемы с Вашей помощью. Теперь попробую всё это реализовать...
Тем более, что в MQL же нельзя объявлять массив как a[ ][ ]? Т.е. нужно хотя бы объявить как a[ ][100]. Это же так? или я ошибаюсь?
А это не очень удобно, т.к. заранее не знаешь какова будет размерность двумерного массива, а резервировать память под массив заранее, в прок - не лучший вариант,
Отлично! :-) Я очень рад, что процесс куда-то движется :-).
.
Двумерные массивы в Mql4 объявлять, конечно же, можно.
И точно так же можно импортировать функцию из Dll
#import myLib
void showMatrix(double & array[][], int rows, int cols);
#import
.
Но здесь есть нюанс: В си мы объявляем функцию, принимающую одномерный массив,
число строк и столбцов void showMatrix(double *array, int rows, int cols);
И array работает как одномерный массив, адресация в котором устроена циклом:
for(line = 0 .. MAX_COL-1)
for(column = 0 .. MAX_COL-1)
array[line*MAX_COL + column] = data[line][column];
.
Т.е. Mql кидает двумерный массив непрерывным буфером.
.
Только не наступайте на те же грабли - функции с шага 3 и 4 используются внутри Вашей Dll,
внутри интерфейсной функции Dll-ины, которая примет от Mql одномерные массивы с числом строк/столбцов.
Она конвернтнет их в ap::real_2d_array, передаст в rmatrixsvd
и уже результат поместит в выходной буфер, размерность строк и столбцов которого
должна быть правильная.
.
Выходной буфер резервируйте, естественно, заранее- это нужно сделать в Mql.
А если размеренности неизвестны, то мое мнение, что нужно сделать
одномерный массив большой размеренности, например
double out[2500];
и массивы из одного элемента для выходных значений кол-во строк/столбцов
double raws[1];
double cols[1];
.
Visual Studio круче. Особенно с Visual Assist'ом. Как в дебилдере работает STL, я не знаю. С юникодом проблемы почти 100%.
Справка Win SDK ни в какое сравнение с MSDN. Ходят слухи, что для интеграции с дельфи компилятор борланда
для плюсов претерпел неположительные изменения.
.
А работа с памятью- это тема для занятия.
Вроде бы теоретически всё понятно, буду приступать к реализации, а там видно будет :-). "Глаза страшат, а руки делают.."
Ещё раз спасибо за ценные указания. Очень бы хотелось реализовать этот алгоритм... А то как обычно, мысль уже ушла далеко стратегически, а вот тактически и практически
приходится её догонять. Надеюсь, что всё у меня получится. Если возникнут у меня вопросы, Вы уж не откажите мне в любезности, помочь советом. Благодарю!
Хотелось бы ещё раз уточнить по поводу размерности динамических массивов.
В MQL одномерный массив можно определить как array[ ], а потом когда будет известно в программе размерность массива N,
то с помощью функции ArrayResize(array, N). Двумерный же массив можно определить только как array[ ][100], т.е. вторую размерность
всё равно надо обязательно знать, а если не знаем, то брать по максимуму, чтобы хватило при любом раскладе. В MQL можно определить
двумерный массив array[ ][ ], компилятор на это не ругается, но функция ArrayResize у станавливает новый размер в первом измерении массива,
для второго измерения подобной функции в MQL нет. Если определить двумерный массив array[N][M], компилятор на это выдаст ошибку, что ожидается
целое число, т.е. размерности нужно определить заранее, по крайней мере второе измерение массива.
В С++ также? Никуда от этого не уйти? Ещё раз хотелось бы уточнить.
В сингулярном разложении используется Библиотека AP для C++ (описание в прикрепленном файле). Там есть некоторые функции, насколько я понял решающие
проблемы динамического первого и второго измерения массивов. Могу ли я ими воспользоваться в моём случае внутри DLL при написании конверторов данных?
void setbounds(int iLow1, int iHigh1, int iLow2, int iHigh2)
Выделение памяти под массив. При этом старое содержимое массива удаляется и освобождается выделенная под него память, затем заново выделяется отдельная область памяти размером (iHigh1-iLow1+1)*(iHigh2-iLow2+1) элементов.
Нумерация элементов в новом массива по первой размерности начинается с iLow1 и заканчивается iHigh1, аналогично для второй размерности.
Содержимое нового массива не определено.
А ещё там есть такая функция:
void setcontent(int iLow1, int iHigh1, int iLow2, int iHigh2, const T *pContent)
Метод аналогичен методу setbounds() за тем исключением, что после выделения памяти в неё копируется содержимое массива pContent[].
Массив pContent содержит двухмерный массив, записанный построчно, т.е. первым идет элемент [iLow1, iLow2], затем [iLow1, iLow2+1] и т.д.
Если я правильно понял, то это именно та функция, которая мне нужна, т.е. она из одномерного массива делает двумерный, т.е. по своей сути и является конвертером.
Я правильно понял?
Библиотека AP для C++
MQL : в одномерном размерность меняем как хотим, да. Потом достаем все по индексам (line * MAX_COL + col).
В двумерном 2я размерность зафиксирована. Т.е. элементы матрицы [15][32] из массива a[100][100] мы уже не cсчитаем.
.
А как работают функции библиотеки AP- я предлагаю Вам проверить.
Не останавливайтесь на Dll. Напишите Exe, его проще запускать и отлаживать.
Вставьте debug print (отладочную печать).
Совет я дать, конечно, могу- но для совета, по-хорошему, нужно это проверять-
писать тестовый код.
.
А насчет содержимого массива и переменных- неважно где-
лучше взять за правило их принудительно, жестко инициализировать.