MATLAB LanguageAan de slag met MATLAB Language


versies

Versie Vrijlating Publicatiedatum
1.0 1984/01/01
2 1986-01-01
3 1987/01/01
3.5 1990-01-01
4 1992-01-01
4.2c 1994/01/01
5.0 Volume 8 1996-12-01
5.1 Deel 9 1997/05/01
5.1.1 R9.1 1997/05/02
5.2 R10 1998-03-01
5.2.1 R10.1 1998/03/02
5.3 R11 1999-01-01
5.3.1 R11.1 1999/11/01
6.0 R12 2000/11/01
6.1 R12.1 2001-06-01
6.5 R13 2002-06-01
6.5.1 R13SP2 2003-01-01
6.5.2 R13SP2 2003/01/02
7 R14 2006-06-01
7.0.4 R14SP1 2004-10-01
7.1 R14SP3 2005-08-01
7.2 R2006a 2006-03-01
7.3 R2006b 2006-09-01
7.4 R2007a 2007-03-01
7.5 R2007b 2007-09-01
7.6 R2008a 2008-03-01
7.7 R2008b 2008-09-01
7.8 R2009a 2009-03-01
7.9 R2009b 2009-09-01
7.10 R2010a 2010-03-01
7.11 R2010b 2010-09-01
7.12 R2011a 2011-03-01
7.13 R2011b 2011-09-01
7.14 R2012a 2012-03-01
8.0 R2012b 2012-09-01
8.1 R2013a 2013/03/01
8.2 R2013b 2013/09/01
8.3 R2014a 2014/03/01
8.4 R2014b 2014/09/01
8.5 R2015a 2015/03/01
8.6 R2015b 2015/09/01
9.0 R2016a 2016/03/01
9.1 R2016b 2016/09/14
9.2 R2017a 2017/03/08

Zie ook: Relatiegeschiedenis van MATLAB op Wikipedia .

Anonieme functies en functiehandvatten

Basics

Anonieme functies zijn een krachtig hulpmiddel van de MATLAB-taal. Het zijn functies die lokaal bestaan, dat wil zeggen: in de huidige werkruimte. Ze bestaan echter niet op het MATLAB-pad zoals een normale functie, bijvoorbeeld in een m-bestand. Daarom worden ze anoniem genoemd, hoewel ze een naam als een variabele in de werkruimte kunnen hebben.

De operator @

Gebruik de operator @ om anonieme functies en functiehandvatten te maken. Om bijvoorbeeld een greep naar de sin functie (sinus) te maken en deze als f :

>> f = @sin
f = 
    @sin
 

Nu is f een handvat voor de sin functie. Net zoals (in het echte leven) een deurklink een manier is om een deur te gebruiken, is een functiehandgreep een manier om een functie te gebruiken. Om f te gebruiken, worden er argumenten aan gegeven alsof het de sin functie is:

>> f(pi/2)
ans =
     1
 

f accepteert invoerargumenten die de sin functie accepteert. Als sin een functie is die nul invoerargumenten accepteert (wat niet het geval is, maar anderen wel, bijvoorbeeld de peaks ), zou f() worden gebruikt om het zonder invoerargumenten aan te roepen.

Aangepaste anonieme functies

Anonieme functies van één variabele

Het is natuurlijk niet handig om een handvat te maken voor een bestaande functie, zoals sin in het bovenstaande voorbeeld. In dat voorbeeld is het een beetje overbodig. Het is echter handig om anonieme functies te maken die aangepaste dingen doen die anders meerdere keren zouden moeten worden herhaald of waarvoor een afzonderlijke functie moet worden gemaakt. Als een voorbeeld van een aangepaste anonieme functie die één variabele als invoer accepteert, som je de sinus en cosinus op in het kwadraat van een signaal:

>> f = @(x) sin(x)+cos(x).^2
f = 
    @(x)sin(x)+cos(x).^2
 

Nu accepteert f één invoerargument genaamd x . Dit werd gespecificeerd met haakjes (...) direct achter de operator @ . f nu een anonieme functie van x : f(x) . Het wordt gebruikt door een waarde van x aan f :

>> f(pi)
ans =
    1.0000
 

Een vector van waarden of een variabele kan ook worden doorgegeven aan f , zolang ze op een geldige manier binnen f worden gebruikt:

>> f(1:3) % pass a vector to f
ans =
    1.1334    1.0825    1.1212
>> n = 5:7;
>> f(n) % pass n to f
ans =
   -0.8785    0.6425    1.2254
 

Anonieme functies van meer dan één variabele

Op dezelfde manier kunnen anonieme functies worden gemaakt om meer dan één variabele te accepteren. Een voorbeeld van een anonieme functie die drie variabelen accepteert:

>> f = @(x,y,z) x.^2 + y.^2 - z.^2
f = 
    @(x,y,z)x.^2+y.^2-z.^2
>> f(2,3,4)
ans =
    -3
 

Anonieme functies parametreren

Variabelen in de werkruimte kunnen worden gebruikt bij de definitie van anonieme functies. Dit wordt parametrisering genoemd. Om bijvoorbeeld een constante c = 2 in een anonieme functie:

>> c = 2;
>> f = @(x) c*x
f = 
    @(x)c*x
>> f(3)
ans =
     6
 

f(3) gebruikte de variabele c als parameter om te vermenigvuldigen met de opgegeven x . Merk op dat als de waarde van c op dit punt op iets anders wordt ingesteld, dan f(3) wordt aangeroepen, het resultaat niet anders zou zijn. De waarde van c is de waarde op het moment van aanmaken van de anonieme functie:

>> c = 2;
>> f = @(x) c*x;
>> f(3)
ans =
     6
>> c = 3;
>> f(3)
ans =
     6
 

Invoerargumenten voor een anonieme functie verwijzen niet naar werkruimtevariabelen

Merk op dat het gebruik van de naam van variabelen in de werkruimte als een van de invoerargumenten van een anonieme functie (dwz het gebruik van @(...) ) de waarden van die variabelen niet zal gebruiken. In plaats daarvan worden ze behandeld als verschillende variabelen binnen het bereik van de anonieme functie, dat wil zeggen: de anonieme functie heeft een eigen werkruimte waar de invoervariabelen nooit verwijzen naar de variabelen uit de hoofdwerkruimte. De hoofdwerkruimte en de werkruimte van de anonieme functie zijn niet op de hoogte van elkaars inhoud. Een voorbeeld om dit te illustreren:

>> x = 3 % x in main workspace
x =
     3
>> f = @(x) x+1; % here x refers to a private x variable
>> f(5)
ans =
     6
>> x
x =
     3
 

De waarde van x uit de hoofdwerkruimte wordt niet gebruikt in f . Ook werd in de hoofdwerkruimte x onaangeroerd gelaten. Binnen het bereik van f zijn de variabelenamen tussen haakjes na de operator @ onafhankelijk van de belangrijkste variabelen in de werkruimte.

Anonieme functies worden opgeslagen in variabelen

Een anonieme functie (of, meer precies, de functiegreep die naar een anonieme functie verwijst) wordt net als elke andere waarde in de huidige werkruimte opgeslagen: in een variabele (zoals hierboven) in een celarray ( {@(x)x.^2,@(x)x+1} ), of zelfs in een eigenschap (zoals h.ButtonDownFcn voor interactieve grafische afbeeldingen). Dit betekent dat de anonieme functie kan worden behandeld als elke andere waarde. Wanneer het in een variabele wordt opgeslagen, heeft het een naam in de huidige werkruimte en kan het worden gewijzigd en gewist net als variabelen die getallen bevatten.

Anders @sin : een functie- @sin (in de vorm van @sin of voor een anonieme functie) is gewoon een waarde die kan worden opgeslagen in een variabele, net zoals een numerieke matrix dat kan zijn.

Geavanceerd gebruik

Functiehandvatten doorgeven aan andere functies

Omdat functiehandvatten als variabelen worden behandeld, kunnen ze worden doorgegeven aan functies die functiehandvatten als invoerargumenten accepteren.

Een voorbeeld: een functie wordt gemaakt in een m-bestand dat een functie-ingang en een scalair getal accepteert. Vervolgens wordt de functiehandle aangeroepen door er 3 aan door te geven en wordt vervolgens het scalaire getal aan het resultaat toegevoegd. Het resultaat is terug.

Inhoud van funHandleDemo.m :

function y = funHandleDemo(fun,x)
y = fun(3);
y = y + x;
 

Sla het ergens op het pad op, bijvoorbeeld in de huidige map van MATLAB. Nu kan funHandleDemo als volgt worden gebruikt, bijvoorbeeld:

>> f = @(x) x^2; % an anonymous function
>> y = funHandleDemo(f,10) % pass f and a scalar to funHandleDemo
y =
    19
 

De handle van een andere bestaande functie kan worden doorgegeven aan funHandleDemo :

>> y = funHandleDemo(@sin,-5)
y =
   -4.8589
 

Merk op hoe @sin een snelle manier was om toegang te krijgen tot de sin functie zonder het eerst op te slaan in een variabele met behulp van f = @sin .

Het gebruik van bsxfun , cellfun en soortgelijke functies met anonieme functies

MATLAB heeft een aantal ingebouwde functies die anonieme functies als invoer accepteren. Dit is een manier om veel berekeningen uit te voeren met een minimaal aantal regels code. Bijvoorbeeld bsxfun , dat element-voor-element binaire bewerkingen uitvoert, dat wil zeggen: het past een functie toe op twee vectoren of matrices op een element-voor-element manier. Normaal gesproken zou dit het gebruik van vereisen for -loops, die vaak toekenning vooraf vereist voor snelheid. Met behulp van bsxfun dit proces versneld. Het volgende voorbeeld illustreert dit met behulp van tic en toc , twee functies die kunnen worden gebruikt om te bepalen hoe lang de code duurt. Het berekent het verschil van elk matrixelement uit het matrix van de matrixkolom.

A = rand(50); % 50-by-50 matrix of random values between 0 and 1

% method 1: slow and lots of lines of code
tic
meanA = mean(A); % mean of every matrix column: a row vector
% pre-allocate result for speed, remove this for even worse performance
result = zeros(size(A));
for j = 1:size(A,1)
    result(j,:) = A(j,:) - meanA;
end
toc
clear result % make sure method 2 creates its own result

% method 2: fast and only one line of code
tic
result = bsxfun(@minus,A,mean(A));
toc
 

Het uitvoeren van het bovenstaande voorbeeld resulteert in twee uitgangen:

Elapsed time is 0.015153 seconds.
Elapsed time is 0.007884 seconds.
 

Deze lijnen komen uit de toc functies, die de verstreken tijd sinds de laatste oproep naar de tic functie afdrukken.

De bsxfun past de functie in het eerste bsxfun op de andere twee bsxfun . @minus is een lange naam voor dezelfde bewerking als het minteken. Een andere anonieme functie of handle ( @ ) dan elke andere functie had kunnen worden opgegeven, zolang deze A en mean(A) als invoer accepteert om een betekenisvol resultaat te genereren.

Vooral voor grote hoeveelheden gegevens in grote matrices kan bsxfun dingen veel versnellen. Het zorgt er ook voor dat code er schoner uitziet, hoewel het misschien moeilijker te interpreteren is voor mensen die MATLAB of bsxfun niet kennen. (Merk op dat in MATLAB R2016a en later veel bewerkingen die voorheen bsxfun gebruikten, bsxfun niet langer nodig hebben; A-mean(A) werkt direct en kan in sommige gevallen zelfs sneller zijn.)

Celmatrices

Elementen van dezelfde klasse kunnen vaak worden samengevoegd tot matrices (met enkele zeldzame uitzonderingen, bijv. Functiehandvatten). Numerieke scalars, standaard van klasse double , kunnen worden opgeslagen in een matrix.

>> A = [1, -2, 3.14, 4/5, 5^6; pi, inf, 7/0, nan, log(0)]
A =
   1.0e+04 *
    0.0001   -0.0002    0.0003    0.0001    1.5625
    0.0003       Inf       Inf       NaN      -Inf
 

Tekens, die van klasse char in MATLAB, kunnen ook in een array worden opgeslagen met een vergelijkbare syntaxis. Een dergelijke array is vergelijkbaar met een string in veel andere programmeertalen.

>> s = ['MATLAB ','is ','fun']
s =
MATLAB is fun
 

Merk op dat ondanks dat ze haakjes [ en ] , de resultaatklassen verschillen. Daarom zijn de bewerkingen die erop kunnen worden uitgevoerd ook verschillend.

>> whos
  Name      Size            Bytes  Class     Attributes

  A         2x5                80  double              
  s         1x13               26  char                
 

In feite is de array s geen array van de strings 'MATLAB ' , 'is ' en 'fun' , het is slechts één string - een array van 13 tekens. U krijgt dezelfde resultaten als deze door een van de volgende situaties zouden worden gedefinieerd:

>> s = ['MAT','LAB ','is f','u','n'];
>> s = ['M','A','T','L','A','B,' ','i','s',' ','f','u','n'];
 

Met een gewone MATLAB-vector kunt u geen mix van variabelen van verschillende klassen of een paar verschillende tekenreeksen opslaan. Dit is waar de cell reeks van pas komt. Dit is een reeks cellen die elk een MATLAB-object kunnen bevatten, waarvan de klasse indien nodig in elke cel kan verschillen. Gebruik accolades { en } rond de elementen om in een celarray op te slaan.

>> C = {A; s}
C = 
    [2x5 double]
    'MATLAB is fun'
>> whos C
  Name      Size            Bytes  Class    Attributes

  C         2x1               330  cell 
 

Standaard MATLAB-objecten van alle klassen kunnen samen in een celarray worden opgeslagen. Merk op dat celmatrices meer geheugen nodig hebben om hun inhoud op te slaan.

Toegang tot de inhoud van een cel wordt gedaan met accolades { en } .

>> C{1}
ans =
   1.0e+04 *
    0.0001   -0.0002    0.0003    0.0001    1.5625
    0.0003       Inf       Inf       NaN      -Inf
 

Merk op dat C(1) verschilt van C{1} . Terwijl de laatste de inhoud van de cel retourneert (en in het voorbeeld een double klasse heeft), retourneert de eerste een celarray die een subarray van C . Evenzo zou D(4:8,1:3) , als D een 10 bij 5 D(4:8,1:3) zou zijn, een subarray van D retourneren met een grootte van 5 bij 3 en waarvan de klasse cell . En de syntaxis C{1:2} heeft geen enkel geretourneerd object, maar rater retourneert het 2 verschillende objecten (vergelijkbaar met een MATLAB-functie met meerdere retourwaarden):

>> [x,y] = C{1:2}
x =
                         1                        -2                      3.14                       0.8                     15625
          3.14159265358979                       Inf                       Inf                       NaN                      -Inf
y =
MATLAB is fun
 

Gegevenstypen

Er zijn 16 fundamentele gegevenstypen of klassen in MATLAB. Elk van deze klassen heeft de vorm van een matrix of matrix. Met uitzondering van functiehandvatten, is deze matrix of matrix minimaal 0 bij 0 groot en kan deze groeien tot een n-dimensionale matrix van elke grootte. Een functiehandgreep is altijd scalair (1 voor 1).

Belangrijk moment in MATLAB is dat u standaard geen typeaangifte of dimensieverklaringen hoeft te gebruiken. Wanneer u een nieuwe variabele definieert, maakt MATLAB deze automatisch aan en wijst de juiste geheugenruimte toe.

Voorbeeld:

a = 123;
b = [1 2 3];
c = '123';

>> whos
  Name      Size            Bytes  Class     Attributes

  a         1x1                 8  double              
  b         1x3                24  double              
  c         1x3                 6  char    
 

Als de variabele al bestaat, vervangt MATLAB de oorspronkelijke gegevens door nieuwe en wijst indien nodig nieuwe opslagruimte toe.

Fundamentele gegevenstypen

Fundamentele gegevenstypen zijn: numeriek, logical , char , cell , struct , table en function_handle .

Numerieke gegevenstypen :

  • Drijvende-kommagetallen ( standaard )

    MATLAB vertegenwoordigt getallen met drijvende komma in het formaat met dubbele precisie of met enkele precisie. De standaardwaarde is dubbele precisie, maar u kunt elk getal één precisie maken met een eenvoudige conversiefunctie:

    a = 1.23;
    b = single(a);
    
    >> whos
      Name      Size            Bytes  Class     Attributes
    
      a         1x1                 8  double              
      b         1x1                 4  single     
     
  • integers

    MATLAB heeft vier ondertekende en vier niet-ondertekende geheelklassen. Ondertekende typen stellen u in staat om zowel met negatieve gehele getallen als met positieve getallen te werken, maar kunnen niet een zo groot aantal getallen vertegenwoordigen als de niet-ondertekende typen omdat één bit wordt gebruikt om een positief of negatief teken voor het getal aan te duiden. Niet-ondertekende typen bieden een breder bereik van getallen, maar deze getallen kunnen alleen nul of positief zijn.

    MATLAB ondersteunt 1-, 2-, 4- en 8-byte opslag voor gehele gegevens. U kunt geheugen en uitvoeringstijd besparen voor uw programma's als u het kleinste gehele getal gebruikt dat geschikt is voor uw gegevens. U hebt bijvoorbeeld geen 32-bits geheel getal nodig om de waarde 100 op te slaan.

    a = int32(100);
    b = int8(100);
    
    >> whos
      Name      Size            Bytes  Class    Attributes
    
      a         1x1                 4  int32              
      b         1x1                 1  int8               
     

    Om gegevens als een geheel getal op te slaan, moet u van dubbel naar het gewenste gehele getal converteren. Als het getal dat wordt omgezet in een geheel getal een fractioneel deel heeft, rondt MATLAB af naar het dichtstbijzijnde gehele getal. Als het fractionele deel exact 0.5 , kiest MATLAB uit de twee even nabije gehele getallen degene waarvoor de absolute waarde groter is.

    a  = int16(456);
     
  • char

    Tekenreeksen bieden opslag voor tekstgegevens in MATLAB. In overeenstemming met de traditionele programmeerterminologie wordt een array (reeks) van tekens gedefinieerd als een tekenreeks. Er is geen expliciet stringtype in retailreleases van MATLAB.

  • logisch: logische waarden van 1 of 0, vertegenwoordigen respectievelijk waar en onwaar. Gebruik voor relationele omstandigheden en array-indexering. Omdat het gewoon WAAR of ONWAAR is, heeft het een grootte van 1 byte.

    a = logical(1);
     
  • structuur. Een structuurmatrix is een gegevenstype dat variabelen van verschillende gegevenstypen groepeert met behulp van gegevenscontainers die velden worden genoemd . Elk veld kan elk type gegevens bevatten. Toegang tot gegevens in een structuur met behulp van puntnotatie van het formulier structName.fieldName.

    field1 = 'first';
    field2 = 'second';
    value1 = [1 2 3 4 5];
    value2 = 'sometext';
    s = struct(field1,value1,field2,value2);
     

    Om toegang te krijgen tot waarde1, is elk van de volgende syntaxis equivalent

    s.first or s.(field1) or s.('first')
     

    We hebben expliciet toegang tot een veld waarvan we weten dat het bij de eerste methode zal bestaan, of geven een string door of maken een string om toegang te krijgen tot het veld in het tweede voorbeeld. Het derde voorbeeld demostreert dat de notatie van punt-haakjes een string neemt, die dezelfde is als opgeslagen in de variabele field1.

  • tabelvariabelen kunnen verschillende grootten en gegevenstypen hebben, maar alle variabelen moeten hetzelfde aantal rijen hebben.

    Age = [15 25 54]';
    Height = [176 190 165]';
    Name = {'Mike', 'Pete', 'Steeve'}';
    T = table(Name,Age, Height);
     
  • cel. Het is erg handig MATLAB-gegevenstype: celarray is een array waarvan elk element ervan een ander gegevenstype en -grootte kan hebben. Het is een zeer krachtig instrument om gegevens naar eigen inzicht te bewerken.

    a = { [1 2 3], 56, 'art'};
     

    of

    a = cell(3);
     
  • functiehandvat slaat een pointer op naar een functie (bijvoorbeeld naar een anonieme functie). Hiermee kunt u een functie doorgeven aan een andere functie of lokale functies van buiten de hoofdfunctie oproepen.

Er zijn veel instrumenten om met elk gegevenstype te werken en ook ingebouwde datatype conversiefuncties ( str2double , table2cell ).

Aanvullende gegevenstypen

Er zijn verschillende aanvullende gegevenstypen die in sommige specifieke gevallen nuttig zijn. Zij zijn:

  • Datum en tijd: arrays om datums, tijd en duur weer te geven. datetime('now') geeft 21-Jul-2016 16:30:16 .

  • Categorische arrays: het gegevenstype voor het opslaan van gegevens met waarden uit een reeks discrete categorieën. Handig voor het opslaan van niet-numerieke gegevens (geheugen effectief). Kan in een tabel worden gebruikt om groepen rijen te selecteren.

    a = categorical({'a' 'b' 'c'});
     
  • Kaartcontainers zijn een gegevensstructuur met een unieke mogelijkheid om te indexeren, niet alleen via scalaire numerieke waarden, maar ook met tekenvector. Indices in de elementen van een kaart worden sleutels genoemd. Deze sleutels, samen met de bijbehorende gegevenswaarden, worden opgeslagen in de kaart.

  • Tijdreeksen zijn gegevensvectoren die na verloop van tijd worden bemonsterd, vaak met regelmatige tussenpozen. Het is handig om de gegevens op te slaan die met tijdstappen zijn verbonden en het heeft veel nuttige methoden om mee te werken.

Hallo Wereld

Open een nieuw leeg document in de MATLAB-editor (in recente versies van MATLAB, doe dit door het tabblad Start van de toolstrip te selecteren en op Nieuw script te klikken). De standaard sneltoets om een nieuw script te maken is Ctrl-n .

Als alternatief typt u edit myscriptname.m om het bestand myscriptname.m te myscriptname.m voor bewerking, of biedt u aan om het bestand te maken als het niet bestaat op het MATLAB-pad.

Typ het volgende in de editor:

disp('Hello, World!');
 

Selecteer het tabblad Editor van de toolstrip en klik op Opslaan als. Sla het document op in een bestand in de huidige map met de naam helloworld.m . Als u een naamloos bestand opslaat, verschijnt er een dialoogvenster om het bestand een naam te geven.

Typ het volgende in het opdrachtvenster MATLAB:

>> helloworld
 

U zou het volgende antwoord moeten zien in het MATLAB-opdrachtvenster:

Hello, World!
 

We zien dat we in het opdrachtvenster de namen van functies of scriptbestanden kunnen typen die we hebben geschreven of die bij MATLAB zijn geleverd om ze uit te voeren.

Hier hebben we het 'helloworld'-script uitgevoerd. Merk op dat het niet nodig is om de extensie ( .m ) te typen. De instructies in het scriptbestand worden uitgevoerd door MATLAB, hier afgedrukt 'Hallo wereld!' met behulp van de disp functie.

Scriptbestanden kunnen op deze manier worden geschreven om een reeks opdrachten op te slaan voor later (her) gebruik.

Jezelf helpen

MATLAB wordt geleverd met veel ingebouwde scripts en functies die variëren van eenvoudige vermenigvuldiging tot gereedschapskisten voor beeldherkenning. Om informatie te krijgen over een functie die u wilt gebruiken type: help functionname in de opdrachtregel. Laten we de help als voorbeeld nemen.

Informatie over het gebruik ervan kan worden verkregen door te typen:

>> help help

in het opdrachtvenster. Dit zal informatie over het gebruik van de functie terug te keren help . Als de informatie die u zoekt nog steeds onduidelijk is, kunt u de documentatiepagina van de functie proberen. Typ gewoon:

>> doc help

in het opdrachtvenster. Dit zal de doorzoekbare documentatie op de pagina te openen voor de functie help verstrekken van alle informatie die u nodig om te begrijpen hoe de 'help' werkt.

Deze procedure werkt voor alle ingebouwde functies en symbolen.

Wanneer u uw eigen functies ontwikkelt, kunt u hun eigen helpsectie laten maken door opmerkingen boven aan het functiebestand of net na de functieverklaring toe te voegen.

Voorbeeld voor een eenvoudige functie multiplyby2 opgeslagen in het bestand multiplyby2.m

function [prod]=multiplyby2(num)
% function MULTIPLYBY2 accepts a numeric matrix NUM and returns output PROD 
% such that all numbers are multiplied by 2

    prod=num*2;
end
 

of

% function MULTIPLYBY2 accepts a numeric matrix NUM and returns output PROD 
% such that all numbers are multiplied by 2

function [prod]=multiplyby2(num)
    prod=num*2;
end
 

Dit is erg handig wanneer u uw code weken / maanden / jaren ophaalt nadat u deze hebt geschreven.

De help en doc functie biedt veel informatie. Als u leert deze functies te gebruiken, kunt u snel vooruitgang boeken en MATLAB efficiënt gebruiken.

Indexeringsmatrices en arrays

MATLAB biedt verschillende methoden om elementen van matrices en arrays te indexeren (toegang):

  • Subscriptindexering - waarbij u de positie van de gewenste elementen in elke dimensie van de matrix afzonderlijk opgeeft.
  • Lineaire indexering - waarbij de matrix wordt behandeld als een vector, ongeacht de afmetingen. Dat betekent dat u elke positie in de matrix met een enkel nummer opgeeft.
  • Logische indexering - waarbij u een logische matrix (en matrix van true en false waarden) gebruikt met dezelfde afmetingen van de matrix die u probeert te indexeren als een masker om op te geven welke waarde moet worden geretourneerd.

Deze drie methoden worden nu in meer detail uitgelegd met behulp van de volgende 3-bij-3 matrix M als een voorbeeld:

>> M = magic(3)

ans = 

       8    1    6
       3    5    7
       4    9    2
 

Subscript indexering

De meest eenvoudige methode om toegang te krijgen tot een element, is het specificeren van de rij-kolomindex. Bijvoorbeeld, toegang tot het element op de tweede rij en derde kolom:

>> M(2, 3)

ans =

      7
 

Het aantal opgegeven subscripts komt exact overeen met het aantal dimensies dat M heeft (twee in dit voorbeeld).

Merk op dat de volgorde van subscripts hetzelfde is als de wiskundige conventie: rijindex is de eerste. Bovendien beginnen MATLAB-indices met 1 en niet met 0 zoals de meeste programmeertalen.

U kunt meerdere elementen tegelijk indexeren door voor elke coördinaat een vector door te geven in plaats van een enkel nummer. Om bijvoorbeeld de hele tweede rij te krijgen, kunnen we specificeren dat we de eerste, tweede en derde kolom willen:

>> M(2, [1,2,3])

ans =

       3    5    7
 

In MATLAB wordt de vector [1,2,3] gemakkelijker gemaakt met de dubbele punt-operator, dwz 1:3 . U kunt dit ook gebruiken bij het indexeren. Om een hele rij (of kolom) te selecteren, biedt MATLAB een snelkoppeling door het opgeven van : De volgende code retourneert bijvoorbeeld ook de hele tweede rij

>> M(2, :)

ans =

       3    5    7
 

MATLAB ook een snelkoppeling voor het specificeren van het laatste element van een afmeting in de vorm van het end zoekwoord. Het end trefwoord zal werken net alsof het was het nummer van het laatste element in die dimensie. Dus als u alle kolommen van kolom 2 tot de laatste kolom wilt, kunt u het volgende schrijven:

>> M(2, 2:end)

ans =

       5    7
 

Subscriptindexering kan beperkend zijn omdat het niet mogelijk is om afzonderlijke waarden uit verschillende kolommen en rijen te extraheren; het zal de combinatie van alle rijen en kolommen extraheren.

>> M([2,3], [1,3])
ans =

       3    7
       4    2
 

Subscriptindexering kan bijvoorbeeld niet alleen de elementen M(2,1) of M(3,3) extraheren. Om dit te doen moeten we lineaire indexering overwegen.

Lineaire indexering

Met MATLAB kunt u n-dimensionale arrays behandelen als eendimensionale arrays wanneer u indexeert met slechts één dimensie. U hebt rechtstreeks toegang tot het eerste element:

>> M(1)

ans = 

       8
 

Merk op dat arrays worden opgeslagen in kolom-hoofdvolgorde in MATLAB, wat betekent dat u toegang krijgt tot de elementen door eerst in de kolommen te gaan. Dus M(2) is het tweede element van de eerste kolom, wat 3 en M(4) zal het eerste element van de tweede kolom zijn, dwz

>> M(4)

ans = 

        1
 

Er zijn ingebouwde functies in MATLAB om subscript-indices om te zetten in lineaire indices en vice versa: respectievelijk sub2ind en ind2sub . U kunt de subscripts ( r , c ) handmatig converteren naar een lineaire index door

idx = r + (c-1)*size(M,1)
 

Om dit te begrijpen, als we in de eerste kolom staan, is de lineaire index gewoon de rij-index. De bovenstaande formule geldt hiervoor omdat voor c == 1 , (c-1) == 0 . In de volgende kolommen is de lineaire index het rijnummer plus alle rijen van de vorige kolommen.

Merk op dat het trefwoord end nog steeds van toepassing is en nu verwijst naar het allerlaatste element van de array, dwz M(end) == M(end, end) == 2 .

U kunt ook meerdere elementen indexeren met behulp van lineaire indexering. Merk op dat als u dat doet, de geretourneerde matrix dezelfde vorm zal hebben als de matrix van indexvectoren.

M(2:4) retourneert een rijvector omdat 2:4 de rijvector vertegenwoordigt [2,3,4] :

>> M(2:4)

ans =

        3    4    1
 

Als een ander voorbeeld retourneert M([1,2;3,4]) een matrix van 2 bij 2 omdat [1,2;3,4] ook een matrix van 2 bij 2 is. Zie de onderstaande code om jezelf te overtuigen:

>> M([1,2;3,4])

ans =

       8        3
       4        1
 

Houd er rekening mee dat indexering met : alone altijd een kolomvector retourneert:

>> M(:)

ans = 

        8
        3
        4
        1
        5
        9
        6
        7
        2
 

Dit voorbeeld illustreert ook de volgorde waarin MATLAB elementen retourneert bij lineaire indexering.

Logische indexering

De derde methode voor indexering is om een logische matrix, dat wil zeggen een matrix met alleen true of false waarden, te gebruiken als masker om de elementen te filteren die u niet wilt. Als we bijvoorbeeld alle elementen van M willen vinden die groter zijn dan 5 , kunnen we de logische matrix gebruiken

>> M > 5

ans =

    1    0    1
    0    0    1
    0    1    0
 

om M te indexeren en alleen de waarden die groter zijn dan 5 als volgt te retourneren:

>> M(M > 5)

ans =

        8
        9
        6
        7
 

Als u wilt dat dit nummer op zijn plaats blijft (dwz de vorm van de matrix behoudt), kunt u het logische compliment toewijzen

>> M(~(M > 5)) = NaN

ans = 

    8      NaN    6
    NaN    NaN    7
    NaN    9      Nan
 

We kunnen ingewikkelde codeblokken met if en for instructies verminderen door logische indexering te gebruiken.

Neem de niet-gevectoriseerde (al verkort tot een enkele lus met behulp van lineaire indexering):

for elem = 1:numel(M)
  if M(elem) > 5
    M(elem) = M(elem) - 2;
  end
end
 

Dit kan met logische indexering worden ingekort tot de volgende code:

idx = M > 5;
M(idx) = M(idx) - 2;
 

Of nog korter:

M(M > 5) = M(M > 5) - 2;
 

Meer over indexeren

Hogere dimensiematrices

Alle bovengenoemde methoden generaliseren in n-dimensies. Als we de driedimensionale matrix M3 = rand(3,3,3) als voorbeeld gebruiken, hebt u toegang tot alle rijen en kolommen van het tweede segment van de derde dimensie door te schrijven

>> M(:,:,2)
 

U hebt toegang tot het eerste element van het tweede segment met behulp van lineaire indexering. Lineaire indexering gaat alleen door naar het tweede segment na alle rijen en alle kolommen van het eerste segment. Dus de lineaire index voor dat element is

>> M(size(M,1)*size(M,2)+1)
 

In MATLAB is elke matrix zelfs n-dimensionaal: het is toevallig zo dat de grootte van de meeste andere n-dimensies één is. Dus, als a = 2 dan is a(1) == 2 (zoals je zou verwachten), maar ook a(1, 1) == 2 , net als a(1, 1, 1) == 2 , a(1, 1, 1, ..., 1) == 2 enzovoort. Deze "extra" dimensies (van maat 1 ) worden singleton-dimensies genoemd . Het commando squeeze zal ze verwijderen, en men kan permute om de volgorde van dimensies om te wisselen (en indien nodig singleton-dimensies introduceren).

Een n-dimensionale matrix kan ook worden geïndexeerd met behulp van een m subscript (waar m <= n). De regel is dat de eerste m-1 subscripts zich normaal gedragen, terwijl het laatste (m'th) subscript verwijst naar de resterende (n-m + 1) dimensies, net zoals een lineaire index zou verwijzen naar een (n-m + 1) dimensionale matrix. Hier is een voorbeeld:

>> M = reshape(1:24,[2,3,4]);
>> M(1,1)
ans =
     1
>> M(1,10)
ans =
    19
>> M(:,:)
ans =
     1     3     5     7     9    11    13    15    17    19    21    23
     2     4     6     8    10    12    14    16    18    20    22    24
 

Retouren van elementen

Als u bij subscriptindexering meer dan één element in meer dan één dimensie opgeeft, retourneert MATLAB elk mogelijk paar coördinaten. Als u bijvoorbeeld M ([1,2], [1,3] probeert), zal MATLAB M(1,1) en M(2,3) retourneren, maar ook M(1,3) en M(2,1) . Dit kan niet intuïtief lijken wanneer u op zoek bent naar de elementen voor een lijst met coördinatenparen, maar overweeg het voorbeeld van een grotere matrix, A = rand(20) (opmerking A is nu 20 bij- 20 ), waar u de kwadrant rechtsboven. In dit geval hoeft u in plaats van elk coördinaatpaar in dat kwadrant op te geven (en dit geval 100 paren) gewoon de 10 rijen en de 10 kolommen die u wilt dus A(1:10, 11:end) . Een dergelijke matrix splitsen komt veel vaker voor dan een lijst met coördinatenparen vereisen.

In het geval dat u een lijst met coördinatenparen wilt krijgen, is de eenvoudigste oplossing om te converteren naar lineaire indexering. Overweeg het probleem waarbij u een vector van kolomindexen hebt die u wilt retourneren, waarbij elke rij van de vector het kolomnummer bevat dat u wilt retourneren voor de overeenkomstige rij van de matrix. Bijvoorbeeld

colIdx = [3;2;1]
 

Dus in dit geval wilt u eigenlijk de elementen terug krijgen op (1,3) , (2,2) en (3,1) . Dus met behulp van lineaire indexering:

>> colIdx = [3;2;1];
>> rowIdx = 1:length(colIdx);
>> idx = sub2ind(size(M), rowIdx, colIdx);
>> M(idx)

ans = 

        6    5    4
 

Een element meerdere keren retourneren

Met subscript en lineaire indexering kunt u een element ook meerdere keren retourneren door de index dus te herhalen

>> M([1,1,1,2,2,2])

ans = 

        8    8    8    3    3    3
 

U kunt dit gebruiken om hele rijen en kolommen te dupliceren, bijvoorbeeld om de eerste rij en de laatste kolom te herhalen

>> M([1, 1:end], [1:end, end])

ans = 

        8    1    6    6 
        8    1    6    6
        3    5    7    7
        4    9    2    2
 

Zie hier voor meer informatie.

Matrices en arrays

In MATLAB is het meest basale gegevenstype de numerieke array. Het kan een scalaire, een 1-D vector, een 2-D matrix of een ND multidimensionale array zijn.

% a 1-by-1 scalar value
x = 1;
 

Om een rijvector te maken, voert u de elementen tussen haakjes in, gescheiden door spaties of komma's:

% a 1-by-4 row vector
v = [1, 2, 3, 4];
v = [1 2 3 4];
 

Om een kolomvector te maken, scheidt u de elementen met puntkomma's:

% a 4-by-1 column vector
v = [1; 2; 3; 4];
 

Om een matrix te maken, voeren we de rijen in zoals eerder gescheiden door puntkomma's:

% a 2 row-by-4 column matrix
M = [1 2 3 4; 5 6 7 8];

% a 4 row-by-2 column matrix
M = [1 2; ...
     4 5; ...
     6 7; ...
     8 9];
 

Merk op dat u geen matrix met ongelijke rij / kolomgrootte kunt maken. Alle rijen moeten dezelfde lengte hebben en alle kolommen moeten dezelfde lengte hebben:

% an unequal row / column matrix
M = [1 2 3 ; 4 5 6 7]; % This is not valid and will return an error

% another unequal row / column matrix
M = [1 2 3; ...
     4   5; ...
     6 7 8; ...
     9   10];     % This is not valid and will return an error
 

Om een vector of een matrix te transponeren, gebruiken we de .' -operator, of de ' operator om zijn Hermitische conjugaat te nemen, wat het complexe conjugaat is van zijn transpositie. Voor echte matrices zijn deze twee hetzelfde:

% create a row vector and transpose it into a column vector
v = [1 2 3 4].';              % v is equal to [1; 2; 3; 4];

% create a 2-by-4 matrix and transpose it to get a 4-by-2 matrix
M = [1 2 3 4; 5 6 7 8].';     % M is equal to [1 5; 2 6; 3 7; 4 8]

% transpose a vector or matrix stored as a variable
A = [1 2; 3 4];
B = A.';                      % B is equal to [1 3; 2 4]
 

Voor arrays van meer dan twee dimensies is er geen directe taalsyntaxis om ze letterlijk in te voeren. In plaats daarvan moeten we functies gebruiken om ze te construeren (zoals ones , zeros , rand ) of door andere arrays te manipuleren (met behulp van functies zoals cat , reshape , permute ). Een paar voorbeelden:

% a 5-by-2-by-4-by-3 array (4-dimensions)
arr = ones(5, 2, 4, 3);

% a 2-by-3-by-2 array (3-dimensions)
arr = cat(3, [1 2 3; 4 5 6], [7 8 9; 0 1 2]);

% a 5-by-4-by-3-by-2 (4-dimensions)
arr = reshape(1:120, [5 4 3 2]);
 

Invoer lezen en uitvoer schrijven

Net als alle programmeertaal is Matlab ontworpen om te lezen en schrijven in een grote verscheidenheid aan formaten. De native bibliotheek ondersteunt een groot aantal tekst-, beeld-, video-, audio- en gegevensindelingen met meer indelingen voor elke versie-update - kijk hier voor de volledige lijst met ondersteunde bestandsindelingen en welke functie u kunt gebruiken om ze te importeren.

Voordat u uw bestand probeert te laden, moet u zich afvragen wat u wilt dat de gegevens worden en hoe u verwacht dat de computer de gegevens voor u organiseert. Stel dat u een txt / csv-bestand in de volgende indeling heeft:

Fruit,TotalUnits,UnitsLeftAfterSale,SellingPricePerUnit
Apples,200,67,$0.14
Bananas,300,172,$0.11
Pineapple,50,12,$1.74
 

We kunnen zien dat de eerste kolom het formaat van Strings heeft, terwijl de tweede, derde Numeriek zijn, de laatste kolom in de vorm van Valuta. Laten we zeggen dat we willen weten hoeveel inkomsten we vandaag met Matlab hebben verdiend en eerst willen we dit txt / csv-bestand laden. Na het controleren van de link, kunnen we zien dat String en Numeriek type txt-bestanden worden afgehandeld door textscan . Dus we kunnen proberen:

fileID = fopen('dir/test.txt'); %Load file from dir
C = textscan(fileID,'%s %f %f %s','Delimiter',',','HeaderLines',1); %Parse in the txt/csv
 

waarbij %s suggereert dat het element een String-type is, %f suggereert dat het element een Float-type is en dat het bestand wordt gescheiden door ",". De optie HeaderLines vraagt Matlab om de eerste N-regels over te slaan, terwijl de 1 direct hierna betekent dat de eerste regel (de kopregel) moet worden overgeslagen.

Nu zijn C de gegevens die we hebben geladen in de vorm van een celmatrix van 4 cellen, die elk de gegevenskolom in het txt / csv-bestand bevatten.

Dus eerst willen we berekenen hoeveel fruit we vandaag hebben verkocht door de derde kolom af te trekken van de tweede kolom, dit kan worden gedaan door:

sold = C{2} - C{3}; %C{2} gives the elements inside the second cell (or the second column)
 

Nu willen we deze vector vermenigvuldigen met de prijs per eenheid, dus eerst moeten we die kolom Strings omzetten in een kolom met getallen en vervolgens omzetten in een numerieke matrix met Matlab's cell2mat het eerste wat we moeten doen is strippen- naast het teken '$', zijn er veel manieren om dit te doen. De meest directe manier is om een eenvoudige regex te gebruiken:

D = cellfun(@(x)(str2num(regexprep(x, '\$',''))), C{4}, 'UniformOutput', false);%cellfun allows us to avoid looping through each element in the cell.
 

Of u kunt een lus gebruiken:

for t=1:size(C{4},1)
   D{t} = str2num(regexprep(C{4}{t}, '\$',''));
end

E = cell2mat(D)% converts the cell array into a Matrix
 

De str2num functie verandert de string met "$" -tekens gestript in numerieke typen en cell2mat verandert de cel met numerieke elementen in een matrix van getallen

Nu kunnen we de verkochte eenheden vermenigvuldigen met de kosten per eenheid:

revenue = sold .* E; %element-wise product is denoted by .* in Matlab

totalrevenue = sum(revenue);
 

Scripts en functies

MATLAB-code kan worden opgeslagen in m-bestanden om opnieuw te worden gebruikt. m-bestanden hebben de extensie .m die automatisch wordt geassocieerd met MATLAB. Een m-bestand kan een script of functies bevatten.

scripts

Scripts zijn eenvoudig programmabestanden die een reeks MATLAB-opdrachten uitvoeren in een vooraf gedefinieerde volgorde.

Scripts accepteren geen invoer en retourneren ook geen uitvoer. Functioneel gezien zijn scripts gelijk aan het typen van opdrachten rechtstreeks in het opdrachtvenster van MATLAB en deze kunnen worden afgespeeld.

Een voorbeeld van een script:

length = 10;
width = 3;
area = length * width;
 

Dit script definieert length , width en area in de huidige werkruimte met respectievelijk de waarde 10 , 3 en 30 .

Zoals eerder vermeld, is het bovenstaande script functioneel gelijk aan het typen van dezelfde opdrachten rechtstreeks in het opdrachtvenster.

>> length = 10;
>> width = 3;
>> area = length * width;
 

functies

Functies zijn in vergelijking met scripts veel flexibeler en uitbreidbaar. In tegenstelling tot scripts kunnen functies invoer accepteren en uitvoer naar de beller retourneren. Een functie heeft zijn eigen werkruimte, dit betekent dat interne bewerkingen van de functies de variabelen van de beller niet zullen veranderen.

Alle functies worden gedefinieerd met dezelfde koptekstindeling:

function [output] = myFunctionName(input)
 

Het function begint met elke functiekop. De lijst met uitgangen volgt. De lijst met uitgangen kan ook een door komma's gescheiden lijst van te retourneren variabelen zijn.

function [a, b, c] = myFunctionName(input)
 

Hierna volgt de naam van de functie die wordt gebruikt om te bellen. Dit is meestal dezelfde naam als de bestandsnaam. We zouden deze functie bijvoorbeeld opslaan als myFunctionName.m .

Na de functienaam volgt de lijst met ingangen. Net als de uitgangen kan dit ook een door komma's gescheiden lijst zijn.

function [a, b, c] = myFunctionName(x, y, z)
 

We kunnen het voorbeeldscript van eerder herschrijven als een herbruikbare functie zoals de volgende:

function [area] = calcRecArea(length, width)
   area = length * width;
end
 

We kunnen functies aanroepen vanuit andere functies, of zelfs vanuit scriptbestanden. Hier is een voorbeeld van onze bovenstaande functie die wordt gebruikt in een scriptbestand.

l = 100;
w = 20;
a = calcRecArea(l, w);
 

Zoals eerder maken we l , w en a in de werkruimte met de waarden 100 , 20 en 2000 respectievelijk.