Библиотека математических функций 1.1

18.12.14

Разработка - Универсальные функции

Привожу тексты различных математических функций, которыми периодически пользуюсь.
Основной акцент ставится на функции работы с матрицами (в 1С в качестве матриц использовались двумерные массивы).
В версии 1.1 функции работы с матрицами немного переписаны для улучшения производительности.

Скачать файлы

Наименование Файл Версия Размер
Конфигурация с интегрированной библиотекой функций
.cf 7,59Kb
45
.cf 1.1 7,59Kb 45 Скачать

Все функции писал сам. Надеюсь, кому-нибудь они будут полезны.

//кумулятивная функция нормального распределения
Функция NormCDF(x) Экспорт
    Base = 1/2+1/Sqrt(6.283185)*(x-Pow(x,3)/6+Pow(x,5)/40-Pow(x,7)/336+Pow(x,9)/3456-Pow(x,11)/42240);
	Если x < 0 Тогда
        Возврат 1-Base;
    Иначе	
        Возврат Base;
    КонецЕсли; 
КонецФункции 

//факториал числа
Функция Factor(x) Экспорт
    Result = 1;
    Для Индекс = 1 По x Цикл
        Result = Result*Индекс;
    КонецЦикла; 
    Возврат Result;
КонецФункции

//транспонирование матрицы
Функция TransMatrix(Знач х) Экспорт
    r1 = х.Количество();
    r2 = х[0].Количество();
    Result = Новый Массив(r2,r1);
	Для Индекс1 = 0 По r1-1 Цикл
		row = х[Индекс1];
        Для Индекс2 = 0 По r2-1 Цикл
            Result[Индекс2][Индекс1] = row[Индекс2];
        КонецЦикла; 
    КонецЦикла; 
    Возврат Result;	
КонецФункции 

//произведение матриц
Функция ProdMatrix(Знач х,Знач у) Экспорт
    кх1 = х.Количество();
    кх2 = х[0].Количество();
    ку1 = у.Количество();
    ку2 = у[0].Количество();
    Result = Новый Массив(кх1,ку2);
	Для Индекс1 = 0 По кх1-1 Цикл
		rowResult = Result[Индекс1];
        Для Индекс2 = 0 По ку2-1 Цикл
            rowResult[Индекс2] = 0;
            Для Индекс3 = 0 По кх2-1 Цикл
                rowResult[Индекс2] = rowResult[Индекс2]+х[Индекс1][Индекс3]*у[Индекс3][Индекс2];
            КонецЦикла; 
            rowResult[Индекс2] = Окр(rowResult[Индекс2],12);
        КонецЦикла; 
    КонецЦикла; 
    Возврат Result;	
КонецФункции

//обратная матрица
Функция InverseMatrix(Знач у) Экспорт
    х = CopyMatrix(у);
    Ранг = х.Количество();
    Result = IdentityMatrix(Ранг);
	Для Индекс = 0 По Ранг-1 Цикл
        Коэффициент = х[Индекс][Индекс];
        Если Коэффициент = 0 Тогда
            Поиск1 = Неопределено;
            Поиск2 = Неопределено;
            Для Индекс1 = Индекс По Ранг-1 Цикл
                Для Индекс2 = Индекс По Ранг-1 Цикл
                    Если х[Индекс2][Индекс1] <> 0 Тогда
                        Поиск1 = Индекс2;
                        Поиск2 = Индекс1;
                    	Прервать;
                    КонецЕсли;         
                КонецЦикла; 
                Если Поиск1 <> Неопределено Тогда
                    Прервать;
                КонецЕсли; 
            КонецЦикла;
            Если Поиск1 = Неопределено Тогда
                ВызватьИсключение "Матрица вырождена";
            КонецЕсли; 
            х = MatrixPermutation(х,Индекс,Индекс,Поиск1,Поиск2);
            Result = MatrixPermutation(Result,Индекс,Индекс,Поиск1,Поиск2);
		КонецЕсли; 
		rowResult = Result[Индекс];
        Для Индекс3 = 0 По Индекс Цикл
            rowResult[Индекс3] = Окр(rowResult[Индекс3]/Коэффициент,12);
		КонецЦикла;
		row = х[Индекс];
        Для Индекс3 = Индекс По Ранг-1 Цикл
            row[Индекс3] = Окр(row[Индекс3]/Коэффициент,12);
        КонецЦикла;
        Для Индекс4 = 0 По Ранг-1 Цикл
            Если Индекс4 <> Индекс Тогда
                Коэффициент = х[Индекс4][Индекс];
                Для Индекс5 = 0 По Индекс Цикл
                    Result[Индекс4][Индекс5] = Окр(Result[Индекс4][Индекс5]-rowResult[Индекс5]*Коэффициент,12);
                КонецЦикла;     
                Для Индекс5 = Индекс По Ранг-1 Цикл
                    х[Индекс4][Индекс5] = Окр(х[Индекс4][Индекс5]-row[Индекс5]*Коэффициент,12);
                КонецЦикла;     
            КонецЕсли; 
        КонецЦикла;
    КонецЦикла;
    Возврат Result;	
КонецФункции

//единичная матрица
Функция IdentityMatrix(Знач х) Экспорт
    Result = Новый Массив(х,х);
	Для Индекс1 = 0 По х-1 Цикл
		row=Result[Индекс1];
        Для Индекс2 = 0 По х-1 Цикл
            row[Индекс2] = ?(Индекс1 = Индекс2,1,0);
        КонецЦикла; 
    КонецЦикла; 
    Возврат Result;	
КонецФункции

//перемещение строк и колонок внутри матрицы
Функция MatrixPermutation(Знач х,Строка0,Столбец0,Строка1,Столбец1) Экспорт
    Result = CopyMatrix(х);
    кх1 = х.Количество();
    кх2 = х[0].Количество();
    Для Индекс1 = 0 По кх1-1 Цикл
        Для Индекс2 = 0 По кх2-1 Цикл
            Строка = Индекс1;
            Столбец = Индекс2;
            Если Строка = Строка0 Тогда
                Строка = Строка1;
            ИначеЕсли Строка = Строка1 Тогда
                Строка = Строка0;    
            КонецЕсли;
            Если Столбец = Столбец0 Тогда
                Столбец = Столбец1;
            ИначеЕсли Столбец = Столбец1 Тогда
                Столбец = Столбец0;    
            КонецЕсли;
            Result = х[Строка][Столбец];
        КонецЦикла; 
    КонецЦикла; 
    Возврат Result;	
КонецФункции

//копия матрицы
Функция CopyMatrix(Знач х) Экспорт
    r1 = х.Количество();
    r2 = х[0].Количество();
    Result = Новый Массив(r2,r1);
    Для Индекс1 = 0 По r1-1 Цикл
        Для Индекс2 = 0 По r2-1 Цикл
            Result[Индекс2][Индекс1] = х[Индекс2][Индекс1];
        КонецЦикла; 
    КонецЦикла; 
    Возврат Result;	
КонецФункции 

//метод наименьших квадратов
Функция MNK(Знач Matrix,Знач Value) Экспорт
    Trans = TransMatrix(Matrix);
    F1 = ProdMatrix(Trans,Matrix);
    F2 = InverseMatrix(F1);
    F3 = ProdMatrix(F2,Trans);
    Weights = ProdMatrix(F3,Value);
    Отклонения = SumMatrix(ProdMatrix(Matrix,Weights),OppositeMatrix(Value));
    Детерминация = 1-ProdMatrix(TransMatrix(Отклонения),Отклонения)[0][0]/ProdMatrix(TransMatrix(Value),Value)[0][0];
    Возврат Новый Структура("Коэффициенты,Детерминация",Weights,Детерминация);
КонецФункции

//матрица плюс скаляр
Процедура MatrixPlusScalar(Matrix,Scalar) Экспорт
    r1 = Matrix.Количество();
    r2 = Matrix[0].Количество();
	Для Индекс1 = 0 По r1-1 Цикл
		row = Matrix[Индекс1];
        Для Индекс2 = 0 По r2-1 Цикл
            row[Индекс2] = row[Индекс2]+Scalar;
        КонецЦикла; 
    КонецЦикла; 
КонецПроцедуры

//минус матрица
Функция OppositeMatrix(Знач х) Экспорт
    r1 = х.Количество();
    r2 = х[0].Количество();
    Result = Новый Массив(r1,r2);
	Для Индекс1 = 0 По r1-1 Цикл
		rowResult = Result[Индекс1];
		row = х[Индекс1]; 
        Для Индекс2 = 0 По r2-1 Цикл
            rowResult[Индекс2] = -row[Индекс2];
        КонецЦикла; 
    КонецЦикла; 
    Возврат Result;	
КонецФункции

//сумма матриц
Функция SumMatrix(Знач х,Знач у) Экспорт
    r1 = х.Количество();
    r2 = х[0].Количество();
    Result = Новый Массив(r1,r2);
	Для Индекс1 = 0 По r1-1 Цикл
		rowResult = Result[Индекс1];
		rowх = х[Индекс1];
		rowу = у[Индекс1]; 
        Для Индекс2 = 0 По r2-1 Цикл
            rowResult[Индекс2] = rowх[Индекс2]+rowу[Индекс2];
        КонецЦикла; 
    КонецЦикла; 
    Возврат Result;	
КонецФункции

//десятичное число в двоичное
Функция DecimalToBinary(х) Экспорт
    Остаток = х;
    Индекс = 0;
    Результат = 0;
    Пока Остаток > 0 Цикл
        Знак = Остаток%2;
        Остаток = (Остаток-Знак)/2;
        Результат = Результат+Знак*Pow(10,Индекс); 
        Индекс = Индекс+1;
    КонецЦикла; 
    Возврат Результат;	
КонецФункции

//коэффициент отклонения двух чисел
Функция RelativeDeviation(х,у,Num = 4) Экспорт
    Возврат Окр(?(х >= у,х/у,у/х),Num)-1;	
КонецФункции 

//модуль числа
Функция AbsValue(х) Экспорт
	Возврат Макс(х,-х);
КонецФункции  

//округление вверх
Функция RoundUp(x,Num = 1) Экспорт
	z = x/Num;
	res = Цел(z);
	Если z <> res Тогда
		z = res+1;
	КонецЕсли; 	
	Возврат z*Num; 
КонецФункции
 


 
 
 
 

 
 
 
 
 
 

Библиотека функций Математические функции Матрицы

См. также

GUID в 1С 8.3 - как с ними быть

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

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    4312    atdonya    22    

41

Переоткрытие внешних обработок

Универсальные функции Платформа 1С v8.3 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    3881    ke.92@mail.ru    16    

60

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    8557    YA_418728146    6    

139

Печать непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    2020    21    progmaster    7    

3

Расширение: Быстрые отборы через буфер [Alt+C] Копировать список, [Alt+V] Вставить список, [Ctrl+C] Копировать из файлов

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    16011    131    sapervodichka    112    

129

Система контроля ведения учета [БСП]

Универсальные функции Механизмы типовых конфигураций БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данном материале рассмотрим типовой алгоритм подсистемы контроля учета БСП в конфигурациях на примерах.

18.07.2022    7196    quazare    8    

108
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. lex27119 18.12.14 10:46 Сейчас в теме
Сам давно хотел написать в 1С функции для работы с матрицами
2. vasiliy_b 284 18.12.14 11:46 Сейчас в теме
Не плохо. Напишите пожалуйста в каких задачах применяете.
4. alex271 363 18.12.14 12:07 Сейчас в теме
(2) vasiliy_b,

Основное применение: задачи корреляционно-регрессионного анализа.
Или, для тех кому эта формулировка мало о чем говорит, функции применяются в задачах, где исследуются зависимости между какими-либо показателями.
ekaterinaeon; Andris_infostart; +2 Ответить
6. Andris_infostart 18.12.14 17:18 Сейчас в теме
(4) вопрос по применению данной обработки: "Подскажите, пожалуйста, возможно ли отображение полученных зависимостей в виде графиков и если да, то какими средствами пользуетесь?"
7. alex271 363 19.12.14 05:50 Сейчас в теме
(6) Andris_infostart,
При желании график можно построить для любых данных.
Функция MNK возвращает два вектора. Один вектор это коэффициенты регрессии, а другой коэффициенты детерминации. Это результаты оценки зависимости.
А что делать с этими результатами личное дело каждого, их можно анализировать программно или визуально, в т.ч. с использованием графиков.
Графики можно строить произвольным способом, в т.ч. средствами платформы 1С или с помощью внешних компонент.
3. necropunk 9 18.12.14 12:06 Сейчас в теме
Тоже спектр задач интересен. Кажется достаточно узкоспециализированной вещью.
5. hexus 3 18.12.14 12:13 Сейчас в теме
Спасибо за полезные инструменты. Иногда действительно нужны подобные функции. Обычно пишется на ходу и забывается до следующего раза. Тут все структурировано.
8. vano-ekt 123 19.12.14 09:51 Сейчас в теме
я как-то матрицы юзал для хитрых скидок в одной торговой самописке на 8.2
Правда не функциями, а запросом делал
9. infoengineer 19.12.14 12:30 Сейчас в теме
Более компактное решение для вычисления факториала с помощью рекурсивной функции:

Функция Факториал(n)
Возврат ?(n <= 1, 1, n * Факториал(n - 1))
КонецФункции
12. alex271 363 19.12.14 13:04 Сейчас в теме
(9) infoengineer,
Соглашусь, но не очень люблю рекурсию, поэтому как-правило заменяю ее циклами (для лучшего понимания).
67. Brawler 453 30.11.20 13:30 Сейчас в теме
(12) и меньшего расхода ресурсов)) слишком дорогие затраты на вызов новой функции дабы сделать примитивное вычисление
SerVer1C; +1 Ответить
13. pbazeliuk 1954 19.12.14 14:44 Сейчас в теме
(9) infoengineer, рекурсия на порядок больше использует памяти, чем цикл.
jif; Идальго; +2 Ответить
14. ruslan0277 4 19.12.14 15:09 Сейчас в теме
(13) pbazeliuk, правильная рекурсия она как произведение искусства - можно смотреть бесконечно. да и выглядит она более понятней и компактней.
cdrw3; starik-2005; +2 Ответить
17. alex271 363 22.12.14 13:36 Сейчас в теме
(14) ruslan0277,
Компактней да, соглашусь.
Насчет того, что рекурсия более понятна - вопрос очень спорный.
Когда код изобилует рекурсиями в нем становится очень трудно разобраться.
А красота кода в данном случае не самое главное. Самое главное в коде - это его производительность и потребление ресурсов.
25. Mr.Rm 23.12.14 11:56 Сейчас в теме
(17) Если от предлагаемых функций требуется производительность, то многое нужно переписать. Сейчас все сделано аккуратным переложением формул.
infoengineer; +1 Ответить
27. alex271 363 24.12.14 05:47 Сейчас в теме
(25) Mr.Rm,
Когда эти функции писались, самым главным была реализация функционала.
Часть проблем с производительностью я решил, весь функционал использующий эти функции отрабатывает достаточно быстро.
Если у Вас есть конкретные предложения по существенному улучшению производительности некоторых функций, то можете их обозначить.
Я предполагаю, что для функции получения обратной матрицы существуют альтернативные алгоритмы и, возможно, мой алгоритм не самый производительный.
В остальной части все написано достаточно оптимально на мой взгляд.
57. ilialin 29.12.14 12:02 Сейчас в теме
(9) infoengineer,
хоспади,
НИКОГДА НЕЛЬЗЯ ВЫЧИСЛЯТЬ ФАКТОРИАЛ РЕКУРСИЕЙ!!!!!!!

К сожалению, эта детская ошибка встречается в большинстве отечественных учебников по программированию. Как заходит речь о рекурсии, так обязательно следует пример с факториалом.
Рекурсия - интересный метод и существует четко определенный класс задач, где она себя прекрасно показывает (и которые проблематично решить без использования оной). Предназначение рекурсии - обход деревьев. Не надо совать ее в другие места.
Elv_Ra; Артано; Mr.Rm; +3 Ответить
58. 987ww765 305 30.12.14 08:50 Сейчас в теме
(57) ilialin, поясните безграмотному почему нельзя? Только потому что рекурсия предназначена для деревьев?
59. Артано 759 31.12.14 11:04 Сейчас в теме
(58) Думаю, что смысл в значительной потере производительности, ради экономии пары строк кода. Я бы конечно высказался не так категорично, но в данном случае претензию считаю обоснованной
10. mikmike 8 19.12.14 12:53 Сейчас в теме
А почему все названия по английски? Неудобно ж переключаться туда сюда.
11. alex271 363 19.12.14 13:02 Сейчас в теме
(10) mikmike,
Во-первых, подстановка работает.
А, во-вторых, главное алгоритм. Если кто-нибудь захочет, всегда можно переименовать.
15. TMV 14 20.12.14 10:12 Сейчас в теме
(11) alex271,
Во-первых, подстановка работает.
Как будет работать подстановка без переключения раскладки?
16. alex271 363 22.12.14 05:53 Сейчас в теме
(15) TMV,
После точки список экспортных функций отображается. Нужная, конечно, сразу может не отобразиться.
А, вообще, это личное дело каждого. Кому как удобно, так и называют.
Я их по английски назвал, т.к. это математические функции. В математике принято функции называть на английском языке.
18. Герасим 1 23.12.14 07:20 Сейчас в теме
А Окр() для округления чем не устраивает?
24. alex271 363 23.12.14 11:28 Сейчас в теме
(18) Герасим,
Функция RoundUp округляет вверх. Функция Окр() этого делать не позволяет.
Например, нужно чтобы 2,1 округлялось до 3, а не до 2. Как Вы это сделаете с помощью функции Окр()?
29. Герасим 1 24.12.14 09:09 Сейчас в теме
(24) alex271, виноват, поторопился)
63. 1cprogr_nsk 106 12.01.15 14:19 Сейчас в теме
зачем на округление вверх городить?!! можно стандартной это к (24) alex271,
Окр(x+0.49, num)
64. alex271 363 13.01.15 05:18 Сейчас в теме
(63) dr.death,
Не соглашусь с Вами.
Точность округления не известна, число которое нужно прибавить будет зависеть от точности.
Например x=2,0001 тогда Окр(x+0,49) = Окр(2,4901) = 2, а нужно 3
19. sashocq 193 23.12.14 09:48 Сейчас в теме
Я бы добавил к статье примечание, что для производительности лучше циклы записывать в одну строку:
Для Индекс1 = 0 По r1-1 Цикл Для Индекс2 = 0 По r2-1 Цикл Result[Индекс2][Индекс1] = х[Индекс1][Индекс2]; КонецЦикла; КонецЦикла;

Время выполнения цикла может уменьшиться в несколько раз. Тут где-то была статья на эту тему. Но листинг в статье, естественно, менять не нужно.
oleg212; Герасим; +2 6 Ответить
33. BorovikSV 1036 25.12.14 01:07 Сейчас в теме
(19) sashocq, производительность возрастает исключительно в режиме отладки, поскольку отладчику не нужно обрабатывать переход на новую строку, искать связанные точки останова и т.д.
В штатном режиме работы 1С предприятия выигрыш ничтожен, для того чтобы превращать структурированный алгоритм в спагетти.

Если быть до конца "дотошным", то :
смена номера строки для виртуальной машины 1С одна из самых "легких" операций.
Виртуальная машина 1С просто выполняет инструкцию вида <1,N>, где 1 - команда интерпретатору "смена текущей строки", N - номер строки.
Если отладчик не подцеплен, то задача сводится к присваиванию 32 разрядного числа некой 32 разрядной переменной, что в свою очередь выглядит как одна команда ассемблера MOV.
Остальные инструкции (увеличение счетчика цикла, проверка на выполнения условий цикла, сложение вычитание и т.д.) требуют помещение и извлечение значений (или переменных) из стека виртуальной машины, что вносит задержку.
К тому же манипуляции с числами занимают больше время чем может показаться. Ведь у 1С числа реализованы особым образом ("длинная арифметика"). И при каждой манипуляции с числом происходит нетривиальная работа, требующая от десятка до сотен машинных тактов.

Другим словами, длительностью выполнения инструкции <1,N>, можно пренебречь, а значит и лепить все в одну строку нет необходимости.
А если нужна быстрая математика - то напишите внешнюю компоненту, и получите прирост от 10 до 1000 раз.
zzz14; Plotks2017; molodoi1sneg; Steelvan; borda4ev; bforce; Mr.Rm; alex271; +8 Ответить
20. sashocq 193 23.12.14 09:52 Сейчас в теме
Поставил "+" как только увидел функцию нормального распределения. Мне как-то понадобилась для одной необычной задачи: нужно было сгенерировать документы в базе случайными цифрами (но для достижения определенных значений за период). Много времени убил на поиск этой функции и, подозреваю, что она так и не правильно у меня заработала.
Кстати, это же ее приближение через ряд Тейлора? Я тогда до этого не додумался.
22. alex271 363 23.12.14 11:10 Сейчас в теме
(20) sashocq,
Совершенно верно, это приближение через ряд Тейлора
21. AlX0id 23.12.14 10:49 Сейчас в теме
В функции MNK есть вызов некоего Math - видимо, так общий модуль называется.. Нужно убрать наверн ;)
23. alex271 363 23.12.14 11:24 Сейчас в теме
(21) AlX0id,
Да, все верно.
Math можно убрать. Потом исправлю.
26. Asmody 23.12.14 15:03 Сейчас в теме
А чем обосновано использование передачи матриц по значению? Требованиями производительности или потребления ресурсов?
28. alex271 363 24.12.14 05:55 Сейчас в теме
(26) Asmody,
В данном случае скорее логикой разработки.
Чтобы передаваемые переменные не изменились, на всякий пожарный, передается только значение.
В принципе, можно проанализировать функции, и существенную часть этих условий выбросить.
30. Nebiros777 5 24.12.14 11:52 Сейчас в теме
Круть, дайте две!!! Коллекция закладок все пополняется и пополняется...
31. DAnry 8 24.12.14 15:03 Сейчас в теме
Плюсанул конечно. Безусловно, статья хорошая и полезная. Но, если честно, в практике програмирования бухгалтерского и управленческого учета в 1С, сложными математическими функциями пользуюсь крайне редко.
32. Mr.Rm 24.12.14 21:49 Сейчас в теме
Например:
Функция NormCDF(x) Экспорт
    x2=x*x;
    Base = 0.5+0.39894228*(x+x2*(x/-6+x2*(x/40+x2*(x/-336+x2*(x/3456+x2*x/-42240)))));
    Возврат ?(x < 0, 1-Base, Base );
КонецФункции 

Это быстрее примерно на 25%.
34. Mr.Rm 25.12.14 22:13 Сейчас в теме
Добавлю, все же, еще одну исправленную функцию.
Функция ProdMatrix(х, у) Экспорт
    кх1 = х.Количество();
    кх2_1 = х[0].Количество()-1;
    ку1 = у.Количество();
    ку2 = у[0].Количество();
    Result = Новый Массив(кх1,ку2);
	Для Индекс1 = 0 По кх1-1 Цикл
		х1=х[Индекс1];
		R1=Result[Индекс1];
        Для Индекс2 = 0 По ку2-1 Цикл
            R = 0;
            Для Индекс3 = 0 По кх2_1 Цикл
                R = R+х1[Индекс3]*у[Индекс3][Индекс2];
            КонецЦикла; 
            R1[Индекс2] = Окр(R,12);
        КонецЦикла; 
    КонецЦикла; 
    Возврат Result;    
КонецФункции
Показать

Округление кажется лишним, но пусть останется.
Не знаю, какой типичный размер матриц у автора, но уже для 4x4 разница вдвое.

И DecimalToBinary(х) тоже нужно переписать, даже не ради производительности.
35. alex271 363 26.12.14 06:07 Сейчас в теме
(34) Mr.Rm,
Округление в этих функциях добавлено не просто так. Я расскажу как оно появилось.
Я написал функцию получения обратной матрицы без округления, но она повисала даже на относительно небольших матрицах.
Проблема оказалась в формате числа. 1С позволяет хранить в переменной числа с очень большой точностью в несколько сотен знаков (я точно не помню, но где-то 400).
При вычислении обратной матрицы совершается большое количество операций, числа становятся длинными и производительность падает практически до нуля.
Поэтому пришлось добавить округление. В 1С жесткая типизация числа по размеру памяти для переменных отсутствует в отличие от других языков, что где-то является плюсом, а где-то минусом.
37. ildarovich 7846 26.12.14 08:27 Сейчас в теме
(35) alex271,
Проблема оказалась в формате числа. 1С позволяет хранить в переменной числа с очень большой точностью в несколько сотен знаков (я точно не помню, но где-то 400).
При вычислении обратной матрицы совершается большое количество операций, числа становятся длинными и производительность падает практически до нуля.
Поэтому пришлось добавить округление
наивно и не похоже на правду
54. alex271 363 29.12.14 08:11 Сейчас в теме
(37) ildarovich,
Тем не менее, все примерно так и было, года три назад
38. Идальго 226 26.12.14 09:17 Сейчас в теме
(35) alex271, боюсь ошибиться, но там вроде двойная точность используется. А с тормозами - да, я тоже сталкивался. Типизация спасает.
39. BorovikSV 1036 26.12.14 10:43 Сейчас в теме
(35) alex271,
В 1С жесткая типизация числа по размеру памяти для переменных отсутствует в отличие от других языков, что где-то является плюсом, а где-то минусом.


в 1С реализована так называемая длинная арифметика. Длинная арифметика всегда - плюс, тем более для бизнес приложений, и тем более что у вас все равно нет возможности использовать чистый DOUBLE. Функция ОКР как раз и является "поводком" для этой длинной арифметики.
Нужно также отметить что при делении 1С ограничивается точностью 27-28 знаками после запятой. Умножение же может довести точность до бесконечности.

Нужно также отдать должное 1С, она реализовала эту самую длинную арифметику довольно хорошо. Есть ряд библиотек которые тормозят не по детски над тем, что 1С делает почти мгновенно. Все таки рекомендую написать ВК по технологии Native и воткнуть ее в свою библиотеку в виде общего шаблона, и выиграете в скорости неимоверно
46. ildarovich 7846 26.12.14 12:41 Сейчас в теме
(39) BorovikSV,
в 1С реализована так называемая длинная арифметика
а пруфы какие-нибудь есть? Что конкретно вы подразумеваете под длинной арифметикой? Хотите сказать, что время выполнения сложения, умножения, деления, например, будет зависеть от числа разрядов в числе. А проверяли? Не заблуждение ли это?
48. Mr.Rm 26.12.14 13:38 Сейчас в теме
(46) ildarovich
Нет, не заблуждение. Если принять время умножения или деления однозначных чисел за единицу, то время умножения 16-разрядных будет примерно 2 единицы, их деления - 2.5. Для полноразрядных чисел формата 308.308 умножение в 90, а деление в 110 раз медленнее.
Легко проверить
49. ildarovich 7846 26.12.14 16:32 Сейчас в теме
50. Mr.Rm 26.12.14 17:16 Сейчас в теме
(49) ildarovich
Так я это и делал, прежде чем цифры писать. Платформа 8.3.5.1248.
51. ildarovich 7846 26.12.14 17:21 Сейчас в теме
(50) Mr.Rm, а приведите обработку или код, если можно ... хотя не нужно - уже нашел объяснение этого феномена.
Числовые величины и в 1С:Предприятии 7.7 и в 1С:Предприятии 8.x представляются как десятичные числа с фиксированной точкой и неограниченной точностью. Сделано это вполне сознательно, так как десятичные числа более адекватны для представления различных величин в программном обеспечении делового назначения.

Если еще точнее, то в 1С:Предприятии 7.7 используется система счисления с основанием 10000, а в 1С:Предприятии 8.x – система счисления с основанием 1000000000. Но, по сути, речь все равно идет о десятичной арифметике. Большее, но кратное десяти основание системы счисления выбрано для повышения эффективности вычислений.

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

В 1С:Предприятии 7.7 при делении точность результата ограничивалась 20-ю десятичными разрядами после точки.

В 1С:Предприятии 8.1 при делении точность результата определяется как точность делимого плюс три разряда по основанию 1000000000. То есть, при делении 1 / 3 результат будет представлен с точностью до 3-х разрядов по основанию 1000000000 или до 27-и десятичных разрядов. А при делении 0.1 / 3 результат будет с точностью до 4-х разрядов по основанию 1000000000 или до 36-и десятичных разрядов.
Хотя происхождение числа 308 все еще непонятно.
52. Mr.Rm 26.12.14 20:24 Сейчас в теме
(51) ildarovich
308 - это максимальная абсолютная величина порядка в стандартном double. Числа с бо́льшим количеством десятичных знаков не смогут быть корректно приведены к double для передачи во внешние функции или компоненты.

Из приведенного объяснения понятно, что используются binary-coded decimals неограниченного (теоретически, практически - см. выше) размера, разрядностью 16 бит в 7.7 и 32 бита в 8.x. Термин "система счисления с основанием ..." кажется тут неподходящим.

Подробнее только из кода ВМ можно понять.
53. ildarovich 7846 26.12.14 22:23 Сейчас в теме
(52) Mr.Rm,
Длинная арифметика позволяет работать с числами до 308 десятичных знаков целой и 306 дробной части
Но, кажется, до вызова функций, где требуется преобразование, это ограничение не существенно. То есть можно работать (умножать, делить, складывать, вычитать) с числами любой точности без ограничений. Получаем лишь замедление, которое нарастает не плавно, а скачками по 9-ть разрядов у операндов. До 9-ти разрядов - одно время. С 10-ти до 18-ти другое и так далее. Это связано с обработкой отдельных мега-разрядов. Кажется, что длительность умножения будет определяться как О(]М/9[ x ]N/9[), где N, M - число разрядов сомножителей, а ]x[ - ближайшее к x сверху целое.

Например, если 2 х 2 будет выполняться за время t, то 2000000000 х 2000000000 за 4t, а 2000000000000000000 х 2000000000000000000 за 8t.

Из (51) также следует, что высказанное в (39)
при делении 1С ограничивается точностью 27-28 знаков после запятой
это неточное утверждение.

Ну и добавлю по теме статьи.
Наиболее ценная в этой подборке функция вычисления обратной матрицы вызывает наибольшие опасения. Из-за очень вольного управления точностью. Могут быть случаи, когда, умножив матрицу на ее обратную, получим далекую от единичной матрицу. Хотя бы максимальный элемент выбирали для исключения. По виду это вроде Гаусса-Жордана метод? Кажется, у него самые большие проблемы с точностью.
В РАУЗ, например, при решении СЛАУ итерационный алгоритм применяется.
47. Mr.Rm 26.12.14 13:29 Сейчас в теме
(39) BorovikSV
При делении 1С дает до 54 знаков после запятой. Длинная арифметика позволяет работать с числами до 308 десятичных знаков целой и 306 дробной части, как раз по порядку double. Можно использовать дробную часть до 324 знаков, но начинаются проблемы при вызове математических функций, т.к. число преобразуется в double, а разрядной сетки не хватает.

Это приводит к очень плохим эффектам. Например, сделаем умножением в цикле x=10e-307 (кстати, в double умещается). Вычислим y=log10(x). И получим какой-то Not-a-Number: ТипЗнч(y) = Число, Строка(y) = ПустаяСтрока, y<0 = Да.
Более того, любые арифметические действия это свойство сохраняют. z=y+1; ТипЗнч(z) = Число, Строка(z) = ПустаяСтрока, и самое интересное z<0 = Да, что приводит к тому, что
Для i=y По 1 Цикл ... КонецЦикла; зависает напрочь.

Значения, возвращенные из мат. функций имеют стандартную разрядность double - 15 знаков.
36. alex271 363 26.12.14 07:17 Сейчас в теме
(34) Mr.Rm,
В версии 1.1 исправлены функции работы с матрицами для улучшения производительности
40. THXO 26.12.14 10:49 Сейчас в теме
http://forum.infostart.ru/forum24/topic122109/message1271074/#message1271074

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


Я считаю, что с таким тезисом глупо вести речь о программировании математики где либо.
да и вообще программист делать такие заявления права не имеет. это просто непрофессионально. имхо, да какое имхо - правда же.
41. BorovikSV 1036 26.12.14 11:13 Сейчас в теме
(40) THXO, Рекурсия может дать более лаконичный код, но при этом жрет стек.
И вообще сила программирования - в выполнении задачи разными способами.
Но в принципе рекурсию не любить невозможно :)
42. THXO 26.12.14 11:21 Сейчас в теме
(41) Лисп и Пролог в вузах сейчас не учат?)
44. Идальго 226 26.12.14 11:26 Сейчас в теме
(42) THXO, а для Лиспа и Пролога всё подругому? ))
43. Идальго 226 26.12.14 11:22 Сейчас в теме
(40) THXO, да фиг знает. Рекурсивные алгоритмы требуют операций со стеком, даже при той же сложности, а значит медленнее и жрут больше памяти. Поэтому не следует пользоваться рекурсией там, где без этого можно обойтись. Хз, именно это автор, по моему, хотел сказать. Что в этом непрофессионального или неверного?
45. THXO 26.12.14 11:32 Сейчас в теме
(43) "но не очень люблю рекурсию" - это свойство считаю крамольным)

также строитель может заявить "очень не люблю алебастр, предпочитаю бетон".
56. alex271 363 29.12.14 08:21 Сейчас в теме
(45) THXO,
У рекурсии достаточно минусов, они все названы в этой теме.
Я не вижу смысла ставить акцент на моей нелюбви рекурсии, обсуждение которой началось с того, что мне предложили изменить код вычисления факториала.
В библиотеке есть много других функций, а данная тема предназначена для обсуждения, прежде всего, библиотеки и ее функций.
55. alex271 363 29.12.14 08:15 Сейчас в теме
(40) THXO,
Что я люблю и что я не люблю - мое личное дело.
Почему Вы считаете, что у Вас есть право определять что мне писать, а что мне не писать?
60. THXO 31.12.14 14:57 Сейчас в теме
(55) я считаю крамольным свойство, а не вас. даже если его озвучит в той форме как у вас всевышний - я буду считать его еретиком)

зачем так подозрительно думать о своей собственной персоне? а то претензия ко мне как от женщины "сама придумала, сама обиделась".)
62. alex271 363 01.01.15 18:22 Сейчас в теме
61. ilialin 31.12.14 16:31 Сейчас в теме
"Для малой группы задач рекурсия позволяет создать простые, элегантные решения. Для несколько большей группы задач она позволяет создать простые, элегантные, трудные для понимания решения. Для большинства задач она создает исключительно запутанные решения - в таких случаях использование простых итераций обычно более понятно..." - Стив Макконнелл. Совершенный код.
----------
Какая цель преследовалась вами при рекомендации использовать рекурсию при вычислении факториала, вместо цикла? Компактность кода? Ну допустим. А что еще? Какие еще преимущества рекурсии в данном случае? А какие недостатки? А такие:
- трудность понимания, что делает данный код (ну ладно, в данном случае функция называется "Факториал", мы знаем как он считается, можем сообразить как работает код; но если цикл в данном случае понимается моментально, то рекурсия потребует больше времени на понимание);
- непредсказуемые затраты памяти;
- большее время выполнения.
Один плюс, три минуса.
----------
"В погоне за оптимизацией можно сделать программный код совершенно нечитаемым. <...> поддержка такого кода станет очень сложным делом. Человек, который не принимал участия в написании этого кода, скорее всего, просто не станет раскапывать этот кладезь оптимизации. А сам разработчик через полгода - год тоже с большим трудом сможет разобраться в том, что же он написал..." - Профессиональная разработка в системе "1С:Предприятие 8", 1 том.
987ww765; +1 Ответить
65. it-al 8 30.01.15 16:30 Сейчас в теме
Можно ли посчитать полином второй степени функцией
Функция MNK(Знач Matrix,Знач Value)
и что помещать в матрицы Matrix,Value
66. alex271 363 31.01.15 12:19 Сейчас в теме
(65) it-al,
Matrix - это матрица исходных данных (параметров), Value - вектор целевых значений. Подробнее смотрите ссылку ru.wikipedia.org/wiki/Метод_наименьших_квадратов
68. s22 19 08.01.21 00:20 Сейчас в теме
Вроде Матрица+Скаляр это сложением матрицы с единичной умноженной на скаляр?
69. RustIG 1301 27.11.23 13:38 Сейчас в теме
(0) Добрый день! Для визуализации матриц можно использовать способ отсюда Матрицы и матричное программирование
Оставьте свое сообщение