[MATLAB] Pobieranie danych z tabeli

0

Mam za zadanie stworzyć program wykonujący pewnie operacje logistyczne na podstawie danych z tabeli. Problem mam następujący: po pobraniu danych nie wiem, jak użyć ich jako liczby. Próbowałem str2num, wszelkiej maści kombinacji, ale po próbie wykonania jakiejkolwiek operacji arytmetycznej pojawia się error. Prosiłbym o pomoc, jak skonwertować całą tablicę do takiego formatu, żeby można było na niej liczyć. I jeszcze jedno: jak ustawiać wartości w tabeli z poziomu kodu?

Działa:

function pushbutton1_Callback(hObject, eventdata, handles)
tableData = get(handles.uitable1, 'data');
A = tableData(1,1)
B = tableData(1,2)

Błąd:

function pushbutton1_Callback(hObject, eventdata, handles)
tableData = get(handles.uitable1, 'data');
A = tableData(1,1);
B = tableData(1,2);
A+B
Undefined operator '+' for input arguments of type 'cell'.

Error in projektMieszanek>pushbutton1_Callback (line 232)
A+B

Error in gui_mainfcn (line 95)
        feval(varargin{:});

Error in projektMieszanek (line 42)
    gui_mainfcn(gui_State, varargin{:});

Error in
matlab.graphics.internal.figfile.FigFile/read>@(hObject,eventdata)projektMieszanek('pushbutton1_Callback',hObject,eventdata,guidata(hObject)) 
Error while evaluating UIControl Callback
1

Obiekty, które otrzymujesz to cell arrays. Możesz sprawdzić zawartość takiego obiektu komendą celldisp(A). Jeśli będą tam macierze, na których chcesz pracować, możesz je wydobyć korzystając z operatora { }, np A{2} wydobędzie zawartość drugiej komórki.

0

W porządku, co mi się udało: wyświetlić całą tabelę w konsoli. Umiem przepisać zawartości stringów/numeryczne z jednej wartości do drugiej. Natomiast gdzie się pojawia problem: nie umiem edytować jednej komórki i wrzucić jej z powrotem do tablicy. Pobieram np.

tableData{1,2}*2

I owszem, wartość jest pobrana, mogę na niej działać, ale jak ustawić tę komórkę z powrotem w tamtej tablicy, pomnożoną już przez dwa? Próbuję różnych metod, ale na ten moment jedyne co mi się udało, to nadpisać cały obiekt tą jedną wartością. Kolejna sprawa: próbuję przemnożyć całą kolumnę i w konsoli nadpisać tablicę. Coś takiego:

setNames = tableData{:,1}.*2
set(handles.uitable2, 'data', setNames);

// error:
Error using  .* 
Too many input arguments.

Jakiś pomysł, jak obsługiwać te zdarzenia?

1
darkrat napisał(a):

W porządku, co mi się udało: wyświetlić całą tabelę w konsoli. Umiem przepisać zawartości stringów/numeryczne z jednej wartości do drugiej. Natomiast gdzie się pojawia problem: nie umiem edytować jednej komórki i wrzucić jej z powrotem do tablicy. Pobieram np.

tableData{1,2}*2

I owszem, wartość jest pobrana, mogę na niej działać, ale jak ustawić tę komórkę z powrotem w tamtej tablicy, pomnożoną już przez dwa? Próbuję różnych metod, ale na ten moment jedyne co mi się udało, to nadpisać cały obiekt tą jedną wartością. Kolejna sprawa: próbuję przemnożyć całą kolumnę i w konsoli nadpisać tablicę. Coś takiego:

setNames = tableData{:,1}.*2
set(handles.uitable2, 'data', setNames);

// error:
Error using  .* 
Too many input arguments.

Jakiś pomysł, jak obsługiwać te zdarzenia?

Przede wszystkim, jeśli mnożysz przez skalar, nie ma potrzeby stosować operator .*, wystarczy zwykłe *.
Dziwię się, że zadziałało Ci w ogóle wyrażenie tableData{:,1}.*2 (czy zgodnie z moją sugestią tableData{:,1}*2). {:,1} sugeruje, że odnosisz się do więcej niż jednej celi (a konkretnie, do wszystkich celi w kolumnie 1. Pomnożenie zadziała tylko gdy w kolumnie byłaby jedna cela i zawierała coś co można pomnożyć przez 2. W tej sytuacji powinieneś jawnie podać wszystkie współrzędne celi.
Wreszcie, setNames nie jest już celą tylko macierzą, wynikiem przemnożenia przez 2 macierzy wydobytej z celi. Jeśli chcesz ją wsadzić z powrotem do uitable2, to musisz ją wcześniej wsadzić do celi, czyli np:

setNames{1} = tableData{1}*2
set(handles.uitable2, 'data', setNames);

0

Spytam jeszcze tylko o jedną rzecz – jakiś odpowiednik solvera z excela w matlabie? Coś na zasadzie, że podaję kilka równań (ograniczenia i funkcje celu), a następnie dostaję wynik?

Przykładowe ograniczenia (można wziąć solve i rozwiązywanie układów liniowych):

x1 + x2 >= 90
0,02*x1 + 0,06*x2 <= 0,03*(x1 + x2)
3*x1 + 5*x2 <= 4*(x1 + x2)

Funkcja celu (jak w tym wypadku?):

F(x1, x2) = 300*x1 + 200*x2 --> min
1

Nie mam pojęcia, jak zapisać przykładowe wyrażenie "3x1 + 5x2 <= 4(x1 + x2)" lub "0,02x1 + 0,06x2 <= 0,03(x1 + x2)". Całościowo, jako f przyjmujemy nasze [300 200], jako A (lewa strona nierówności) A = [1 1; 0.02 0.05; 3 5];, a jako b wpisałem [90; 0.03; 4], ale pojawia się błąd. Trzeba przepisać jeszcze owe "*(x1+x2)" i tutaj się wysypuje. Samo wywołanie funkcji wygląda tak: linprog(f,A,b). Masz może pomysł, jak to zapisać?

Nie tak. Na postawie Twoich równań ze wcześniejszego wpisu, wydaje mi się, że:
A = [-1 -1; -0,01 0,03; -1 1], b = [-90 0 0], f = [300 200].
Niestety, nie mogę tego sprawdzić, bo nie mam Matlaba, ale spróbuj.

1 użytkowników online, w tym zalogowanych: 0, gości: 1