Умножение матриц пакетным запросом

29.07.13

Разработка - Запросы

Функция для умножения матриц, заданных ТаблицамиЗначений. Все вычисления в одном пакетном запросе.

Разместите в теле модуля нижеприведенные функции.

Предварительно подготовьте две числовые мартрицы с типом значения ТаблицаЗначений  (условно А и В). Либо программно, либо на форме с помощью элементов управления ТабличноеПоле.  Имена колонок могут быть любыми. Размерности таблиц должны удовлетворять условию  А(n x m) , В(m x k).

Осуществите вызов функции ПроизведениеМатриц(А, Б).
В результате будет получена таблица произведения двух  матриц С(n x k). Результат можно загрузить в ТабличноеПоле, как и показано на рисунке.

 

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

Функция ПодготовитьИсходнуюТаблицу(ТЗ, Литера)

    ИсходнаяТ = ТЗ.Скопировать();	
	ш = 1;
	Для каждого Колонка Из ИсходнаяТ.Колонки Цикл Колонка.Имя = "elem" + ш;	ш = ш + 1; КонецЦикла;
	ИсходнаяТ.Колонки.Добавить("i", Новый ОписаниеТипов("Число", , ,Новый КвалификаторыЧисла(12,0)));
	ш = 1;
	Для каждого Стр Из ИсходнаяТ Цикл Стр.i = ш; ш = ш + 1;	КонецЦикла;

	Возврат ИсходнаяТ
	
КонецФункции

Функция ПолучитьЗапросДекомпозиция(м, Литера)

	ЗапросДекомпозиция = "//";
	Для ш = 1 По м Цикл
		
		ЗапросДекомпозиция = ЗапросДекомпозиция +  " Объединить все 
		|ВЫБРАТЬ Таб.i как i, "+ш+"  как j, Таб.elem"+ш+" как elem 
		|"+?(ш=1, "Поместить Таб", "")+"
		| ИЗ Исходная"+Литера+" КАК Таб
		|";
	
	КонецЦикла;
	
	ЗапросДекомпозиция = СтрЗаменить(ЗапросДекомпозиция, "Таб", "Таб"+Литера);
	ЗапросДекомпозиция = СтрЗаменить(ЗапросДекомпозиция, "// Объединить все", "") +";";
	
	Возврат ЗапросДекомпозиция

КонецФункции // ()

Функция ПолучитьЗапросКомпозиция(м)

	ЗапросКомпозицияСоединения = ""; ЗапросКомпозицияПоля = "";	ЗапросКомпозиция = "";
	ЗапросНумерацияСтрок = "Выбрать ИсходнаяА.i Поместить НумерацияСтрок Из ИсходнаяА как ИсходнаяА;";
	Для ш = 1 По м Цикл
		ЗапросКомпозицияПоля = ЗапросКомпозицияПоля + ", РезультатТаблица"+ш+".c  как c" +ш;
		ЗапросКомпозицияСоединения = ЗапросКомпозицияСоединения +  "
		|Левое Соединение РезультатТаблица как РезультатТаблица"+ш+"  По РезультатТаблица"+ш+".j = "+ш+" И РезультатТаблица"+ш+".i = НумерацияСтрок.i";
	КонецЦикла; 
	
	ЗапросКомпозиция = " Выбрать " + ЗапросКомпозицияПоля+ " Из НумерацияСтрок Как НумерацияСтрок " + ЗапросКомпозицияСоединения;

	Возврат ЗапросНумерацияСтрок + СтрЗаменить(ЗапросКомпозиция,"Выбрать ,", "Выбрать ")

КонецФункции // ()


Функция ПроизведениеМатриц(ТабА, ТабБ)
	
    мА = ТабА.Колонки.Количество(); мБ = ТабБ.Колонки.Количество();
	
	Если Не мА = ТабБ.Количество() Тогда
		Сообщить("Неверные размерности матриц!", СтатусСообщения.Важное); Возврат Неопределено;
	КонецЕсли;
	
	Запрос = Новый Запрос;
	ЗапросТекст =  //Исходные матрицы с колонкой с нумерацией строк
	"ВЫБРАТЬ * ПОМЕСТИТЬ ИсходнаяА ИЗ &ТабА КАК ТабА; ВЫБРАТЬ * ПОМЕСТИТЬ ИсходнаяБ ИЗ &ТабБ КАК ТабБ;";
	//Разбор матрицы                                          
	ЗапросТекст = ЗапросТекст + ПолучитьЗапросДекомпозиция(мА, "А") + ПолучитьЗапросДекомпозиция(мБ, "Б");
	//Умножение
	ЗапросТекст = ЗапросТекст +   
	"ВЫБРАТЬ ТабА.i КАК i, ТабБ.j КАК j, СУММА(ТабА.elem * ТабБ.elem) КАК c
	|Поместить РезультатТаблица	
	|ИЗ ТабА КАК ТабА ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТабБ КАК ТабБ ПО ТабА.j = ТабБ.i
	|СГРУППИРОВАТЬ ПО ТабА.i, ТабБ.j;  ";   
	//Сбор матрицы
	Запрос.Текст = ЗапросТекст + ПолучитьЗапросКомпозиция(мБ); 
	
	Запрос.УстановитьПараметр("ТабА", ПодготовитьИсходнуюТаблицу(T1, "а"));                                                                                                    
	Запрос.УстановитьПараметр("ТабБ", ПодготовитьИсходнуюТаблицу(T2, "б"));
	
	Возврат Запрос.Выполнить().Выгрузить();

КонецФункции // ()

 

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

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

12000 руб.

02.09.2020    169295    937    403    

905

Запросы Программист Бесплатно (free)

Увидел cheatsheet по SQL и захотелось нарисовать подобное, но про запросы.

18.10.2024    11394    sergey279    18    

65

Запросы Программист Платформа 1С v8.3 Запросы Конфигурации 1cv8 Бесплатно (free)

Столкнулся с интересной ситуацией, которую хотел бы разобрать, ввиду её неочевидности. Речь пойдёт про использование функции запроса АВТОНОМЕРЗАПИСИ() и проблемы, которые могут возникнуть.

11.10.2024    6339    XilDen    36    

83

Запросы Программист Запросы Бесплатно (free)

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

16.08.2024    9070    user1840182    5    

28

Математика и алгоритмы Запросы Программист Платформа 1С v8.3 Запросы Бесплатно (free)

Рассмотрим быстрый алгоритм поиска дублей с использованием hash функции по набору полей шапки и табличных частей.

08.07.2024    2727    ivanov660    9    

22

Запросы СКД Программист Стажер Система компоновки данных Россия Бесплатно (free)

Часто при разработке отчетов в СКД возникает ситуация, когда не совсем понятно, почему отчет выводит не те данные, которые нужны, либо не выводит вовсе. Возникает потребность увидеть конечный запрос, который формирует СКД. Как это сделать, рассмотрим в этой статье.

15.05.2024    10220    implecs_team    6    

48

Запросы Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Часто поступают задачи по произвольному распределению общих сумм. После распределения иногда пропадают копейки. Суть решения добавить АвтоНомерЗаписи() в ВТ распределения, и далее используя функции МАКСИМУМ или МИНИМУМ можем положить разницу копеек в первую или последнюю строку знаменателя распределения.

11.04.2024    3624    andrey_sag    10    

38
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. ildarovich 7939 29.07.13 23:55 Сейчас в теме
Качественное решение непростой задачи. Но я не совсем согласен с самой идеей использования таблиц значений для работы с матрицами. Таблица значений "заточены" под работу со строками-записями. И рано или поздно это даст о себе знать. В том числе и при вводе и выводе. Матрицы лучше хранить и обрабатывать в виде, получаемом в Вашем случае после функции "декомпозиции", убрав нулевые значения.
2. zaxarovsky 111 30.07.13 08:47 Сейчас в теме
(1) ildarovich, спасибо!
Да, я понял, что хранить и обрабатывать так будет удобно. Тут как раз-таки проблемки с вводом-выводом имеются. А как иначе, если нужно допустим вручную вводить значения да еще чтобы это выглядело привычно?
Полагаю, только для матриц большой размерности это будет играть роль в плане быстродействия.
3. Synoecium 786 28.11.13 15:15 Сейчас в теме
само умножение конечно выглядит элегантно)
а вот по поводу ввода матрицы в запрос, советую использовать подготовленную на встроенном языке таблицу значений. Что-то вроде:
Для Строка=0 По ИсходнаяТаблица.Количество() Цикл
Для Столбец=0 По ИсходнаяТаблица.Колонки.Количество() Цикл
новСтрока = ТаблицаЗапроса.Добавить();
новСтрока.i = Строка;
новСтрока.j = Столбец;
новСтрока.Значение = ИсходнаяТаблица[i][j];
КонецЦикла
КонецЦикла

а затем работать в запросе с "уплощенной" таблицей. На собственном опыте убедился что объединение большого количества подзапросов очень медленно работает. Например, в УПП, запрос к табличной части документа "Табель учета рабочего времени" работает в несколько раз медленнее (объединение 120 таблиц), чем запрос к подготовленной таблице значений.
4. zaxarovsky 111 28.11.13 15:40 Сейчас в теме
(3) Synoecium,
Тут вроде это не особо критично, так как всего (м) таблиц объединяется.
Хотя, в конкретных приложениях, может так и следует поступить. Спасибо!
5. RustIG 1833 27.11.23 13:42 Сейчас в теме
(0) Добрый день! Всегда пугало умножение матриц запросами. Вот попробовал по-другому Матрицы и матричное программирование
Оставьте свое сообщение