Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Matlab - funkcja GA - Matlab Attempt to execute script as a function

timoglok 29 Kwi 2015 22:42 2361 31
  • #1 29 Kwi 2015 22:42
    timoglok
    Poziom 10  

    Witam, mam problem z błędem jak w tytule. Czym to może być spowodowane?

    Kod: fortran
    Zaloguj się, aby zobaczyć kod


    Kod: fortran
    Zaloguj się, aby zobaczyć kod

    0 29
  • #2 29 Kwi 2015 23:04
    -psiak-
    Poziom 32  

    Wykonuj w trybie krokowym a zobaczysz który wiersz powoduje ten błąd.

    0
  • #3 29 Kwi 2015 23:10
    timoglok
    Poziom 10  

    Error in ==> ga at 12
    [x,val,exitflag,output,population,scores] = ga(@funkcja,30,options);

    0
  • #4 29 Kwi 2015 23:55
    -psiak-
    Poziom 32  

    No to co robi ta @ przed funkcja?
    Poczytaj uważnie o lambdach (funkcjach nienazwanych).

    0
  • #7 30 Kwi 2015 19:11
    timoglok
    Poziom 10  

    witaj Marvinn, udało mi się ten problem obejść u uruchomić tą funkcję GA.
    Ale teraz mam problem z przekazaniem obliczonych wartości do Simulinka.
    Po zakomentowaniu instrukcji sim('model') i podaniu stałego fc skrypt się uruchamia.

    Kod: fortran
    Zaloguj się, aby zobaczyć kod


    Jak z funkcji wyciągnąć te 3 zmienne?

    0
  • #8 30 Kwi 2015 22:00
    Marvinn8686
    Poziom 20  

    W modelu simulinkowym musisz użyć bloczka "From workspace" pozwala on załadować zmienne wyliczone wcześniej przez skrypt http://www.mathworks.com/help/simulink/slref/fromworkspace.html
    Przykłady również tutaj: http://www.goddardconsulting.ca/simulink-interfacing-with-matlab.html

    Ogólnie jednak, powinno to działać nawet bez tego bloczka, uruchamiasz skrypt, który wylicza dane używane następnie przez model. W twoim przypadku, są one wyliczane wewnątrz funkcji fc, czyli nie są zmiennymi globalnymi, a lokalnymi. Co prawda model jest wywoływany również wewnątrz funkcji, czyli w tym samym zakresie co parametry, jednak z tego co kojarzę model widzi tylko zmienne globalne. Zrób tak, żeby funkcja fc zwracała wszystkie potrzebne parametry

    Kod: C
    Zaloguj się, aby zobaczyć kod

    0
  • #9 30 Kwi 2015 23:44
    timoglok
    Poziom 10  

    A co z funkcją dopasowania fc=calka(end); ?

    Kod: fortran
    Zaloguj się, aby zobaczyć kod


    ??? Error: File: ga.m Line: 11 Column: 1
    Function definitions are not permitted in this context.

    0
  • #10 01 Maj 2015 15:31
    Marvinn8686
    Poziom 20  

    Odnosiłem się tylko do tego jak w skrypcie ustawić wartość parametrów, aby były widoczne w modelu. Nie udzieliłeś informacji co to za funkcja ani co w ogóle ma ona robić. Nikt tu nie jest wróżbitą i nie zgadnie co jest twoim celem do zrobienia. W pierwszym poście wkleiłeś kod bez żadnego opisu. W jakim celu jest funkcja calka na końcu skryptu, gdy model jest już wywołany to chciałbym wiedzieć.

    0
  • #11 01 Maj 2015 15:38
    -psiak-
    Poziom 32  

    Zastanów się nad przykładem:

    Code:
    function [A,B,C]=LiczWszystko(x)
    
      ...
    end;

    function B=LiczTylkoB(x)
       [A,B,C]=LiczWszystko(x)
    end;

    0
  • #12 01 Maj 2015 16:05
    timoglok
    Poziom 10  

    Marvinn8686,
    fc=calka(end); jest to ostatnia wartość wektora calka który jest wskaźnikiem jakości czyli całką kwadratu uchybu wyznaczonego w modelu. W algorytmie genetycznym zastępuje wskaźnik dopasowania.

    -psiak-, rozumiem ten przykład, ale funkcja dopasowania musi być wyznaczana po uruchomieniu symulacji, czyli poza funkcją

    0
  • #13 01 Maj 2015 16:29
    -psiak-
    Poziom 32  

    ... czyli w jednym przypadku używasz LiczTylkoB(x) zaś w drugim LiczWszystko(x) ...

    0
  • #14 01 Maj 2015 17:42
    timoglok
    Poziom 10  

    teraz już nie kumam

    0
  • #15 01 Maj 2015 19:25
    -psiak-
    Poziom 32  

    Code:
    [x,val,exitflag,output,population,scores] = ga(@LiczTylkoB,30,options);
    
    [Kp,Ti,Td,Ka]=LiczWszystko(end);

    0
  • #16 01 Maj 2015 19:49
    timoglok
    Poziom 10  

    -psiak- czy Ty to uruchamiałeś?
    Ja rozumiem że Ty nie chcesz zrobić wszystkiego za mnie. Ale ta ostatnia instrukcja jest zła.

    0
  • Pomocny post
    #17 01 Maj 2015 20:03
    -psiak-
    Poziom 32  

    @timoglok, to nie jest gotowa instrukcja do wklejenia, to nieco bardziej rozpisany schemat który tobie od kilku postów radzi @Marvinn8686, a którego nie jesteś w stanie zaadaptować w związku z brakiem podstaw.

    0
  • #18 01 Maj 2015 20:20
    timoglok
    Poziom 10  

    no może i tak

    0
  • Pomocny post
    #19 01 Maj 2015 20:20
    Marvinn8686
    Poziom 20  

    timoglok napisał:
    Marvinn8686,
    fc=calka(end); jest to ostatnia wartość wektora calka który jest wskaźnikiem jakości czyli całką kwadratu uchybu wyznaczonego w modelu. W algorytmie genetycznym zastępuje wskaźnik dopasowania.

    Chyba robisz to nie po kolei, albo ja nie łapię sensu tego co chcesz zrobić.
    1. Najpierw uruchamiasz optymalizację algorytmem genetycznym. Przekazujesz do niej funkcję fc (tę z zakodowanymi na sztywno parametrami). Rezultaty optymalizacji [x,val,exitflag,output,population,scores] są ignorowane.
    2. Następnie ustawiasz parametry regulatora do wykorzystania w modelu (funkcja fc(x), gdzie rozumiem dla testu są ustawione na 1).
    3. Później używasz ich w simulinkowym modelu sim('model');
    4. tworzysz zmienną fc, do której przypisujesz ostatnią wartość wektora "calka".
    5. Koniec.

    0
  • #20 01 Maj 2015 21:16
    timoglok
    Poziom 10  

    Twój opis pasuje do algorytmu po tych wszystkich zmianach.

    Spójrz na ten algorytm z pierwszego postu:
    do GA chcę przekazać funkcję która zwraca mi wartość całka(end).

    1. Uruchamiam Ga - losuje się 30sto elementowy wektor 0 i 1
    2. Dziele go na 3 części i przeliczam na dziesiętne odpowiednio Kp,Ti,Td
    3. Uruchamiam symulację i wyznaczam całka(end) która jest przekazywana do GA
    4. Jeżeli nie ma warunku stopu to generuje się następny 30 elementowy wektor itd.

    0
  • Pomocny post
    #21 01 Maj 2015 23:20
    Marvinn8686
    Poziom 20  

    Od takiego opisu powinieneś zacząć :) Generalnie zamysł dobry, jednak:
    1. Nazwa funkcji fc(x) i zmienna fc o tej samej nazwie - to nie najlepszy pomysł.
    2. Funkcja celu przekazywana do algorytmu genetycznego faktycznie powinna dla każdego "osobnika" dokonać jego oceny poprzez zdekodowanie jego parametrów do Kp,Ti,Td a następnie uruchomić model.mdl, aby ocenić wartość uchybu ustalonego.

    Ustaliliśmy już, że zmienne jeśli wyliczone parametry będą zmiennymi lokalnymi, to będzie problem z ich widocznością w modelu.
    W takim razie jednak potrzebujemy funkcji celu następującej postaci:

    Code:
    function error = fc(x)
    
    % tutaj dekodowanie parametrow osobnika x do Kp, Ti, Td (lokalne, z malej litery)
    kp=1;
    ti=1;
    td=1;
    % zapisanie wyliczonych parametrow do globalnej przestrzeni nazw
    assignin('base','Kp',kp);
    assignin('base','Ti',ti);
    assignin('base','Td',td);
    % 3. na wszelki wypadek ustawiamy zeby model korzystal z base workspace gdzie zapisalismy zmienne
    options = simset('SrcWorkspace','base');

    % uruchomienie modelu, wynik dzialania zapisany do "calka"
    sim('model',[],options);

    % wartosc zwracana z funkcji
    error = calka(end);


    Natomiast główny wykonywany skrypt wywołuje tylko algorytm genetyczny z tak spreparowaną funkcją celu
    Code:
    clear all; clc;
    
    ps=60;     
    options = gaoptimset('PopulationType','bitString','PopulationSize',ps,'TolFun',0, ...
         'FitnessLimit',0,'MutationFcn',{@mutationuniform,0.5});
    options = gaoptimset(options,'PlotFcns',{@gaplotbestf,@gaplotscores});
    [x,val,exitflag,output,population,scores] = ga(@fc,30,options);

    0
  • #22 02 Maj 2015 00:13
    timoglok
    Poziom 10  

    Dzięki wielkie :)
    a jak to uruchomić? Bo jak nazwę pierwszy skrypt z funkcją jako error.m to nie mogę go otworzyć.

    I czy nie można zrobić tak?

    Code:

    options = simset('SrcWorkspace','Current');
    sim('model',[],options);


    i wtedy model użyje zmiennych lokalnych ?

    0
  • Pomocny post
    #23 02 Maj 2015 00:23
    Marvinn8686
    Poziom 20  

    Może to przejdzie, byłoby nawet lepiej nie używać zmiennych globalnych tylko lokalne. Nazwij nie error, tylko fc. error to wartość zwracana z funkcji.

    0
  • #24 02 Maj 2015 00:41
    timoglok
    Poziom 10  

    dziękuję jeszcze raz :)
    Optymalizacja działa.

    Czasami się wysypuje przy dużych wartościach funkcji np:
    error = 8.7132e+068
    ??? Error using ==> makeState at 55
    Your fitness function must return a scalar value.
    Mimo że jest skalarem?

    0
  • #25 02 Maj 2015 10:49
    Marvinn8686
    Poziom 20  

    Nie spotkałem się z czymś takim, może po prostu wartość jest za duża. Trudno powiedzieć, ale dobrze byłoby zapewnić pracę modelu bez wysypywania się od czasu do czasu. Możesz na wyjściu modelu, przed ToWorkspace::calka dać bloczek saturation
    http://www.mathworks.com/help/simulink/slref/saturation.html
    i ustawić tam, że każda wartość większa niż zadana będzie ścinana. Minimalizujesz funkcję, więc olbrzymie liczby typu e+068 możesz ścinać do wartości nie powodującej wysypywania się (np. e+50). Może to nieeleganckie obejście, ale trzeba by pogrzebać żeby ustalić dokładnie o co chodzi z tym komunikatem.

    0
  • #26 02 Maj 2015 11:22
    timoglok
    Poziom 10  

    Podoba mi się to obejście ale niestety nie działa :(
    Upper limit - 1000
    error = 1000
    ??? Error using ==> makeState at 55
    Your fitness function must return a scalar value.
    Error in ==> gaunc at 42
    state = makeState(GenomeLength,FitnessFcn,Iterate,output.problemtype,options);
    Error in ==> ga at 303
    [x,fval,exitFlag,output,population,scores] = gaunc(FitnessFcn,nvars, ...
    Error in ==> skrypt at 8
    [x,val,exitflag,output,population,scores] = ga(@fc,GenomeLength,options);

    To samo co wcześniej. Jak ustawie GenomeLength na < 15 to działa prawie zawsze ale daje słabe wyniki.

    0
  • #27 02 Maj 2015 11:27
    Marvinn8686
    Poziom 20  

    Czyli nie duża wartość jest problemem, najprawdopodobniej czasem faktycznie error ma inny rozmiar. Jak się wysypie to sprawdź czy error faktycznie jest skalarem, tj. size(error) powinno zwrócić 1x1. Ewentualnie dodaj w funkcji fc wypisywanie wartości error na konsolę przed zwróceniem. Pokaż aktualny kod fc wyliczający error.

    0
  • #28 02 Maj 2015 12:30
    timoglok
    Poziom 10  

    error = 1.0846
    rozmiar = 1 1
    ??? Error using ==> makeState at 55
    Your fitness function must return a scalar value.

    Code:

    function error = fc(x)
    % Wzmacniacz
    Ka = 10;                                       % 10-400   
    Ta = 0.1;                                      % 0.02-0.1 
    % konwerter bin to dec
    il_bitow=30;
    l=il_bitow/3;
    conv = 2.^[0:l-1];
    %%%%% Kp %%%%%
    s = x(1:l);     
    fliplr(s);         
    s = sum(conv.*s); 
    a = -2;           
    b = 2;
    Kp = a+s*(b-a)/(2^l-1)
    %%%%%% Ti %%%%
    s = x(l+1:2*l);
    fliplr(s);
    s = sum(conv.*s);
    a = -2;
    b = 2;
    Ti = a+s*(b-a)/(2^l-1)
    %%%%%% Td %%%%%%
    s = x(2*l+1:3*l);
    fliplr(s);
    s = sum(conv.*s);
    a = -2;
    b = 2;
    Td = a+s*(b-a)/(2^l-1)
    options = simset('SrcWorkspace','current');
    sim('AGmodel',[],options);                % rozpoczęcie symulacji
    error=calka(end)                          % ostatnia wartość całki uchybu

    0
  • #29 02 Maj 2015 14:49
    Marvinn8686
    Poziom 20  

    Czyli jednak error nie jest skalarem. Tak jest za każdym razem, czy tylko czasami?
    Rozumiem, że całka to powinien być wektor 1xN z którego bierzesz ostatnią wartość. Jeśli error nie jest skalarem tylko czasami, dobrze byłoby ustawić w funkcji fc breakpoint który złapie taki przypadek, tj. dodać na samym końcu

    Code:
    if not(isscalar(error))
    
        tmp = error; % tutaj breakpoint, podejrzyj wtedy wektor calka czy wszystko z nim w porządku
    end

    0
  • #30 02 Maj 2015 15:21
    timoglok
    Poziom 10  

    Błąd ten jest tak w 8/10 uruchomień algorytmu.
    Całka jest rozmiaru Nx1 i biorę z niej ostatnią wartość.
    Zauważyłem że w każdej iteracji calka ma inny rozmiar tj:
    ans = 808 1
    ans = 595 1
    ans = 599 1 ale to jest chyba zależne od max step size
    calka(end) jest zawsze 1x1
    Do tego breakpointa nie wchodzi w ogóle.

    Pojawił się po kilku iteracjach inny błąd, może ma coś wspólnego?

    ??? Error using ==> makeState at 51
    GA cannot continue because user supplied fitness function failed with the following error:
    Error using ==> sim
    Derivative input 1 of 'AGmodel/Integrator' at time 16.79139471649778 is Inf or NaN. Stopping simulation. There may be a singularity in the solution.
    If not, try reducing the step size (either by reducing the fixed step size or by tightening the error tolerances).

    0