I cannot solve a problem in Scilab because it get stucked because of round-off errors. I get the message
!--error 9999
Error: Round-off error detected, the requested tolerance (or default) cannot be achieved. Try using bigger tolerances.
at line 2 of function scalpol called by :
at line 7 of function gram_schmidt_pol called by :
gram_schmidt_pol(a,-1/2,-1/2)
It’s a Gram Schmidt process with the integral of the product of two functions and a weight as the scalar product, between -1 and 1.
gram_schmidt_pol
is the process specially designed for polynome, and scalpol
is the scalar product described for polynome.
The a
and b
are parameters for the weigth, which is (1+x)^a*(1-x)^b
The entry is a matrix representing a set of vectors, it works well with the matrix [[1;2;3],[4;5;6],[7;8;9]]
, but it fails with the above message error on matrix eye(2,2)
, in addition to this, I need to do it on eye(9,9) !
I have looked for a «tolerance setting» in the menus, there is some in General->Preferences->Xcos->Simulation
but I believe this is not for what I wan’t, I have tried low settings (high tolerance) in it and it hasn’t change anything.
So how can I solve this rounf-off problem ?
Feel free to tell me my message lacks of clearness.
Thank you.
Edit: Code of the functions :
// function that evaluate a polynomial (vector of coefficients) in x
function [y] = pol(p, x)
y = 0
for i=1:length(p)
y = y + p(i)*x^(i-1)
end
endfunction
// weight function evaluated in x, parametrized by a and b
// (poids = weight in french)
function [y] = poids(x, a, b)
y = (1-x)^a*(1+x)^b
endfunction
// scalpol compute scalar product between polynomial p1 and p2
// using integrate, the weight and the pol functions.
function [s] = scalpol(p1, p2, a, b)
s = integrate('poids(x,a, b)*pol(p1,x)*pol(p2,x)', 'x', -1, 1)
endfunction
// norm associated to scalpol
function [y] = normscalpol(f, a, b)
y = sqrt(scalpol(f, f, a, b))
endfunction
// finally the gram schmidt process on a family of polynome
// represented by a matrix
function [o] = gram_schmidt_pol(m, a, b)
[n,p] = size(m)
o(1:n) = m(1:n,1)/(normscalpol(m(1:n,1), a, b))
for k = 2:p
s =0
for i = 1:(k-1)
s = s + (scalpol(o(1:n,i), m(1:n,k), a, b) / scalpol(o(1:n,i),o(1:n,i), a, b) .* o(1:n,i))
end
o(1:n,k) = m(1:n,k) - s
o(1:n,k) = o(1:n,k) ./ normscalpol(o(1:n,k), a, b)
end
endfunction
Редактор системы нечеткого вывода. Построение нечетких систем в Scilab.
Система нечеткого вывода по Мамдани
В SciFLT (FLT — fuzzy logic toolbox) реализованы все основные функции, необходимые для создания и модифицирования систем нечеткого вывода (СНВ). Для построения системы нечеткого вывода в командной строке основного окна SciLAB необходимо набрать команду editfls. Эта команда вызывает графический редактор систем нечеткого вывода.
В меню необходимо выбрать File->New FLS->тип создаваемой системы (Мамдани или Сугено).
Создадим систему нечеткого вывода по Мамдани. В левой панели появится Tree-control – дерево создаваемой нечеткой системы. Сначала выбираем в нем пункт Description и заполняем появившуюся справа форму. В ней необходимо указать имя редактируемой системы, комментарии (не обязательно), виды T-нормы и S-конормы, тип операторов дополнения, импликации, агрегации и метод дефаззификации.
Для системы по Мамдани обычно выбирают типы операторов, указанные на рис.9. Далее определяем состав входных и выходных переменных. Для этого необходимо выбрать в дереве (в левом окне fls Edit or см. рис.9)пункты Inputs и Outputs соответственно. В окне справа появится число переменных, их список, а также кнопки Add, Delete и Exit. Добавляем новые переменные кнопкой Add.
Сохранение проектируемой системы в рабочее пространство среды SciLAB производится с помощью пункта меню File –> Export–> To workspace. В этом случае данные сохраняются до окончания сеанса работы с SciLAB. Для сохранения данных на диск после окончания сеанса работы применяется соответствующий пункт того же меню – To FLS file… .
Редактор переменных. Для редактирования переменных (переименования, задания диапазона значений, связывания функциями принадлежности) необходимо выбрать в списке входных или выходных переменных нужную. Тогда в правом окне появится редактор переменной (рис.10):
1) в нем необходимо задать имя;
2) диапазон допустимых значений;
3) с помощью кнопки Add внизу окна добавить функции принадлежности. Их можно также удалять, пометив щелчком мыши и нажав кнопку Delete (checked).
Рис. 9. Описание системы
Рис. 10. Редактор переменных (входная переменная из примера 1 Discount)
Редактор функций принадлежности (ФП) является инструментом, который позволяет отображать и редактировать любые ФП, ассоциированные (связанные) со всеми входными и выходными переменными разрабатываемой СНВ. Редактируют ФП текущей переменной, изменяя характеристики ФП (наименование, тип и числовые параметры). Таким образом, при построении СНВ необходимо посредством редактора ФП определить соответствующие функции для каждой из входных и выходных переменных.
Редактор правил вывода. После того, как указано количество входных и выходных переменных, определены их наименования и построены соответствующие ФП, в СНВ необходимо включить правила вывода. Для этого в дереве контроля выбирается пункт Rules. (в левом окне fls Edit or см. рис.9).
Основываясь на описаниях входных и выходных переменных, определенных в редакторе ФП, редактор правил вывода формирует структуру правила автоматически. От пользователя требуется лишь связать значения входных и выходных переменных, выбирая из списка заданных ранее ФП, и определить логические связки между ними. Также допускается использование логического отрицания (НЕ) и изменение весов правил в диапазоне от 0 до 1.
Правила вывода отображаются в окне в следующей форме:
где i — номер входной переменной, ji — номер ФП i-ой переменной, k – номер выходной переменной, n – количество входных переменных, m – количество выходных переменных, w – вес правила. Круглые скобки заключают в себе обязательные параметры, квадратные – необязательные, а угловые – альтернативные параметры (один на выбор).
Пример 1. Создание системы нечеткого вывода (СНВ) по Мамдани.
В качестве примера, иллюстрирующего метод построения СНВ, рассмотрим следующую ситуацию. Необходимо оценить степень инвестиционной привлекательности конкретного бизнес-проекта на основании данных о ставке дисконтирования и периоде окупаемости.
Шаг первый. Вызываем редактор для создания СНВ, набирая в командной строке editfls. В появившемся окне редактора создаем новую систему по Мамдани. Заполняем описание как показано на рис. 9. Добавляем 2 входные переменные и 1 выходную переменную.
В результате получаем следующую структуру СНВ: два входа, механизм нечеткого вывода по Мамдани, один выход. Объявляем первую переменную как discont, а вторую – period, которые, соответственно, будут представлять ставку дисконтирования и период окупаемости бизнес-проекта. Наименование выходной переменной, на основании которой принимается решение о степени инвестиционной привлекательности бизнес-проекта, задается как rate. Сохраним создаваемую модель под именем Invest. На рис. 9 представлено текущее состояние окна редактора СНВ.
Шаг второй. Каждой входной и выходной переменной поставим в соответствие набор ФП. Для discont определяем диапазон базовой переменной от 5 до 50 (единица измерения – проценты). Такой же диапазон выбираем для ее отображения. Добавим три ФП, тип которых – trimf, и присвоим им наименования – small, middle, big, соответственно, небольшой, средней и большой ставке дисконтирования (см. рис. 10). Переменной period диапазон базовой переменной определен равным [3,36] (единица измерения – месяцы), поставлены в соответствие три ФП типа gaussmf с наименованиями — short, normal, long. Таким образом, переменная срока окупаемости бизнес-проекта будет принимать следующие значения: короткий, обычный и длительный срок окупаемости (рис.11). Для переменной rate определяем: базовая переменная изменяет значение в диапазоне [0, 1], семантика описывается тремя ФП типа trimf c наименованиями: bad, normal, good (рис. 12). В графическом виде переменные представлены на рис. 13,14 (меню View -> Plot variables).
Шаг третий. Заключительным этапом построения СНВ является определение набора правил, которые задают связь входных переменных с выходными.
Рис.11. Входная переменная Period
Рис.12. Выходная переменная Rate
Рис. 13. Графическое представление входных переменных
Рис. 14. Графическое представление выходной переменной
Для этого в редакторе правил вывода определим:
ЕСЛИ discont = small И period = short ТО rate = good
ЕСЛИ discont = НЕ small И period = long ТО rate = bad
ЕСЛИ discont = middle И period = normal ТО rate = normal
ЕСЛИ discont = big И period = short ТО rate = normal
Текущее состояние окна редактора правил вывода показано на рис. 15.
Рис.15. Редактор правил вывода
Средство просмотра поверхности вывода. Для этого существует функция plotsurf. Она вызывается из командной строки окна SciLAB и имеет следующие параметры вызова:
plotsurf( fls [, ivar , ovar , vivar [,npart[,mod]]]) .
Параметры функции: fls – имя fls-структуры;
ivar – вектор входных переменных (задаются порядковые номера входных переменных, которые необходимо построить);
ovar – скаляр, номер выходной переменной;
vivar – вектор значений входных переменных;
npart – вектор, number of partitions domain for each input variable;
mod – скаляр, вид отображения поверхности на экране. 1 – grayscale, 2 – jetcolormap, 3 – hotcolormap, 4 – internalcolormap.
Необходимо сохранить полученную систему в рабочее пространство среды SciLAB с помощью пункта меню File –> Export–> To workspace.
Внимание! В этом случае данные сохраняются до окончания сеанса работы с SciLAB. Для сохранения данных на диск после окончания сеанса работы применяется соответствующий пункт того же меню – To FLS file…
Пример 2.
plotsurf(fls,[1 2],1,[0 0]);
Поверхность вывода, соответствующая правилам вывода примера 1 показана на рис.16.
Рис. 16. Поверхность нечеткого вывода
Пример 3. Разработать простую нечёткую экспертную систему по оцениванию привлекательности путёвки. Использовать пять входных лингвистических переменных – Accommodation (проживание), food (питание), excursions (наличие экскурсий), health services (оздоровительные услуги), price(цена) и одну выходную – tip (привлекательность).
Для решения подобных задач с нечёткой логикой в SciLAB используется компонент под названием Fuzzy Logic Toolbox. Чтобы начать работу с ней нам нужно установить его, для этого запустим программу и во вкладке Инструменты нажмём Управление модулями Atoms (рис.17).
Далее в открывшемся окне следует перейти в папку все модули и выбрать Fuzzy Logic Toolbox и нажать установить. Когда компонент установиться следует перезапустить программу. После запуска программы в командном окне появиться запись об успешной загрузке компонента (рис.18).
Для дальнейшей работы с нечёткой логикой нам необходимо набрать в командном окне команду editfls, после этого откроется окно для работы с нечёткой логикой (рис.19).
Рис. 17. Вкладка запуска управления модулями Atoms
Рис. 18. Вывод в командном окне об успешной загрузке компонента Fuzzy Logic Toolbox
Рис. 19. Параметры по алгоритму Mamdani
Создадим систему с нечёткой логикой по алгоритму Mamdani. Для этого во вкладе File выберем Newfls – Mamdani. Справа в окне Description зададим параметры:
Name: permit
S-Norm Class: Maximum
T-Norm Class: Minimum
Complemet: One
Implication method: Minimum
Aggregation method: Maximum
Дальше создадим пять входных переменных Accommodation, food, excursions, health services, и price. Для того чтобы создать переменные в левой колонке выберите вкладку Inputs и в правом окне нажмите кнопку Add (рис.20).
Рис. 20. Настройки параметров входной переменной Accomodation
После создания переменной двойным нажатием левой кнопкой мыши выберите нашу переменную и нажмите Edit. В поле редактирования доступны такие параметры как: name (имя переменной) и range (интервал значений). Ниже располагается поле редактирования членов функций, которые можно добавить, нажав кнопку Add. Каждому члену функции можно задать name (имя), type (тип), par (параметры).
Параметры для первой входной переменной Accomodation (см. рис.20):
Information:
Nro. Member functions = 3
Member functions:
Name = 3 stars Type = gauss2mf Par = 13.59 -4 13.59 4
Name = 4 stars Type = gauss2mf Par = 13.59 46 13.59 54
Name = 5 stars Type = gauss2mf Par = 13.59 96 13.59 104
Параметры для второй входной переменной food (рис.21):
Information:
Nro. Member functions = 3
Member functions:
Name = BB Type = gauss2mf Par = 13.59 -4 13.59 4
Name = HB Type = gauss2mf Par = 13.59 46 13.59 54
Name = FB Type = gauss2mf Par = 13.59 96 13.59 104
Параметры для третьей входной переменной Excursions (рис.22):
Information:
Nro. Member functions = 2
Name = Haven’t Type = gauss2mf Par = 13.59 -4 13.59 4
Name = Have Type = gauss2mf Par = 13.59 96 13.59 104
Рис. 21. Настройки параметров входной переменной food
Рис. 22. Настройки параметров входной переменной Excursions
Параметры для четвёртой входной переменной health services (рис.23):
Information:
Name = health services
Nro. Member functions = 2
Member functions:
Name = Haven’t Type = gauss2mf Par = 13.59 -4 13.59 4
Name = Have Type = gauss2mf Par = 13.59 96 13.59 104
Рис.23. Настройки параметров входной переменной health services
Параметры для пятой входной переменной price (рис.24):
Information:
Nro. Member functions = 3
Member functions:
Name = 30000 Type = gauss2mf Par = 13.59 -4 13.59 4
Name = 30000 to 50000 Type = gauss2mf Par = 13.59 46 13.59 54
Name = 50000 to 70000 Type = gauss2mf Par = 13.59 96 13.59 104
Рис.24. Настройки параметров входной переменной price
Для добавления выходной переменной существует вкладка Outputs и процесс создания ничем не отличается от входных переменных. Добавим переменную tip и установим значения параметров (рис.25):
Information:
Nro. Member functions = 3
Member functions:
Name = Poor Type = gauss2mf Par = 13.59 -4 13.59 4
Name = Good Type = gauss2mf Par = 13.59 46 13.59 54
Name = Excellent Type = gauss2mf Par = 13.59 96 13.59 104
Рис.25. Настройки параметров выходной переменной tip
Завершающим этапом создания простой нечёткой экспертной системы является создание правил во вкладе Rules (рис.26).
Рис.26. Правила для определения привлекательности путёвки
Источник
FeodoriA 0 / 0 / 0 Регистрация: 27.10.2017 Сообщений: 1 |
||||||||
1 |
||||||||
При выполнении вычисления появляется ошибка. В чем может быть проблема27.10.2017, 13:36. Показов 1637. Ответов 1 Метки нет (Все метки)
Здравствуйте, при выполнении данного вычисления:
Появляется следующая ошибка:
Прошу помогите разобраться с проблемой.
__________________
0 |
olbond 143 / 133 / 42 Регистрация: 11.03.2013 Сообщений: 274 |
||||
30.10.2017, 03:07 |
2 |
|||
ode: external must be real проверьте правильность задания функции «f», возвращает комплексное значение в первой же точке:
0 |
Я не могу решить задачу в Scilab, потому что она зависает из-за ошибок округления. я получаю сообщение
!--error 9999
Error: Round-off error detected, the requested tolerance (or default) cannot be achieved. Try using bigger tolerances.
at line 2 of function scalpol called by :
at line 7 of function gram_schmidt_pol called by :
gram_schmidt_pol(a,-1/2,-1/2)
Это процесс Грама Шмидта с интегралом от произведения двух функций и весом в виде скалярного произведения от -1 до 1. gram_schmidt_pol
— это процесс, специально разработанный для полинома, а scalpol
— скалярное произведение, описанное для полинома.
a
и b
являются параметрами для веса, который равен (1+x)^a*(1-x)^b
.
Запись представляет собой матрицу, представляющую набор векторов, она хорошо работает с матрицей [[1;2;3],[4;5;6],[7;8;9]]
, но не работает с вышеуказанной ошибкой сообщения на матрице eye(2,2)
, в дополнение к этому мне нужно сделать это на глаз(9,9) !
Я искал «настройку допуска» в меню, некоторые из них есть в General->Preferences->Xcos->Simulation
, но я считаю, что это не то, чего я не хочу, я пробовал в нем низкие настройки (высокий допуск), и это не помогло. ничего не изменить.
Итак, как я могу решить эту проблему округления?
Не стесняйтесь сказать мне, что моему сообщению не хватает ясности. Спасибо.
Изменить: Код функций:
// function that evaluate a polynomial (vector of coefficients) in x
function [y] = pol(p, x)
y = 0
for i=1:length(p)
y = y + p(i)*x^(i-1)
end
endfunction
// weight function evaluated in x, parametrized by a and b
// (poids = weight in french)
function [y] = poids(x, a, b)
y = (1-x)^a*(1+x)^b
endfunction
// scalpol compute scalar product between polynomial p1 and p2
// using integrate, the weight and the pol functions.
function [s] = scalpol(p1, p2, a, b)
s = integrate('poids(x,a, b)*pol(p1,x)*pol(p2,x)', 'x', -1, 1)
endfunction
// norm associated to scalpol
function [y] = normscalpol(f, a, b)
y = sqrt(scalpol(f, f, a, b))
endfunction
// finally the gram schmidt process on a family of polynome
// represented by a matrix
function [o] = gram_schmidt_pol(m, a, b)
[n,p] = size(m)
o(1:n) = m(1:n,1)/(normscalpol(m(1:n,1), a, b))
for k = 2:p
s =0
for i = 1:(k-1)
s = s + (scalpol(o(1:n,i), m(1:n,k), a, b) / scalpol(o(1:n,i),o(1:n,i), a, b) .* o(1:n,i))
end
o(1:n,k) = m(1:n,k) - s
o(1:n,k) = o(1:n,k) ./ normscalpol(o(1:n,k), a, b)
end
endfunction
1 ответ
По умолчанию подпрограмма Scilab integrate
пытается достичь абсолютной ошибки не более 1e-8 и относительной ошибки не более 1e-14. Это разумно, но его обработка относительной ошибки не принимает во внимание проблемы, возникающие, когда точное значение равно нулю. (См. Как рассчитать относительную ошибку, когда истинное значение равно нулю?). По этой причине даже простой
integrate('x', 'x', -1, 1)
Выдает ошибку (в Scilab 5.5.1).
И вот что происходит в процессе работы вашей программы: некоторые интегралы равны нулю. Есть два решения:
(A) Откажитесь от границы относительной ошибки, указав ее как 1:
integrate('...', 'x', -1, 1, 1e-8, 1)
(B) Добавьте некоторую константу к интегрируемой функции, затем вычтите из результата:
integrate('100 + ... ', 'x', -1, 1) - 200
(Последнее должно работать в большинстве случаев, хотя, если интеграл будет ровно -200, у вас снова будет та же проблема)
Вышеприведенное работает для gram_schmidt_pol(eye(2,2), -1/2, -1/2)
, но для больших, скажем, gram_schmidt_pol(eye(9,9), -1/2, -1/2)
выдает ошибку «Интеграл, вероятно, расходится или медленно сходится».
Похоже, процедура адаптивной интеграции не справляется с теми функциями, которые есть у вас. Вместо этого можно использовать простой inttrap
, который просто применяет правило трапеций. Поскольку при x=-1 и 1 функция poids не определена, конечные точки должны быть исключены.
function [s] = scalpol(p1, p2, a, b)
t = -0.9995:0.001:0.9995
y = poids(t,a, b).*pol(p1,t).*pol(p2,t)
s = inttrap(t,y)
endfunction
Чтобы это работало, другие связанные функции должны быть векторизованы (* и ^ заменены на .* и .^, где это необходимо):
function [y] = pol(p, x)
y = 0
for i=1:length(p)
y = y + p(i)*x.^(i-1)
end
endfunction
function [y] = poids(x, a, b)
y = (1-x).^a.*(1+x).^b
endfunction
Результат гарантированно сработает, хотя точность может быть немного ниже: вы получите некоторые числа, такие как 3D-16, которые на самом деле являются нулями.
-1
Community
13 Апр 2017 в 15:19