Zoeken…


Noem geen variabele met een bestaande functienaam

Er is al een functiesom sum() . Als gevolg hiervan, als we een variabele met dezelfde naam noemen

sum = 1+3;

en als we proberen de functie te gebruiken terwijl de variabele nog steeds in de werkruimte bestaat

A = rand(2);
sum(A,1)

we krijgen de cryptische fout :

Subscript indices must either be real positive integers or logicals.

clear() eerst de variabele en gebruik vervolgens de functie

clear sum

sum(A,1)
ans =
       1.0826       1.0279

Hoe kunnen we controleren of er al een functie bestaat om dit conflict te voorkomen?

Gebruik which() met de vlag -all :

which sum -all
sum is a variable.
built-in (C:\Program Files\MATLAB\R2016a\toolbox\matlab\datafun\@double\sum)   % Shadowed double method
...

Deze output vertelt ons dat sum eerst een variabele is en dat de volgende methoden (functies) erdoor worden overschaduwd, dwz dat MATLAB eerst zal proberen onze syntaxis op de variabele toe te passen in plaats van de methode te gebruiken.

Wat je ziet is NIET wat je krijgt: char vs cellstring in het opdrachtvenster

Dit is een basisvoorbeeld gericht op nieuwe gebruikers. Het richt zich niet op het verklaren van het verschil tussen char en cellstring .


Het kan gebeuren dat je de ' in je snaren ' kwijt wilt, hoewel je ze nooit hebt toegevoegd. In feite zijn dit artefacten die het opdrachtvenster gebruikt om onderscheid te maken tussen sommige typen.

Er wordt een string afgedrukt

s = 'dsadasd'
s =
dsadasd

Er wordt een celstring afgedrukt

c = {'dsadasd'};
c = 
    'dsadasd'

Merk op dat de enkele aanhalingstekens en de inspringing artefacten zijn om ons te laten weten dat c een cellstring plaats van een char . De string bevindt zich namelijk in de cel, dwz

c{1}
ans =
dsadasd

De transponisten

  • .' is de correcte manier om een vector of matrix in MATLAB zetten.
  • ' is de juiste manier om de complexe geconjugeerde transpositie (aka Hermitische conjugaat) van een vector of matrix in MATLAB te nemen.

Merk op dat voor de transponering .' , er staat een periode voor de apostrof. Dit is in overeenstemming met de syntaxis voor de andere elementgewijze bewerkingen in MATLAB: * vermenigvuldigt matrices,. .* Vermenigvuldigt elementen van matrices samen. De twee opdrachten lijken erg op elkaar, maar zijn conceptueel zeer verschillend. Net als andere MATLAB-opdrachten zijn deze operators "syntactische suiker" die tijdens runtime wordt omgezet in een "juiste" functieaanroep. Net zoals == een evaluatie van de eq- functie wordt, denk aan .' als afkorting voor transpose . Als u alleen ' (zonder het punt) zou schrijven, gebruikt u in plaats daarvan de opdracht ctranspose , die de complexe geconjugeerde transpositie berekent, die ook bekend staat als de Hermitische conjugaat , vaak gebruikt in de natuurkunde. Zolang de getransponeerde vector of matrix een reële waarde heeft, produceren de twee operatoren hetzelfde resultaat. Maar zodra we omgaan met complexe getallen , zullen we onvermijdelijk in de problemen komen als we niet de "juiste" afkorting gebruiken. Wat "correct" is, hangt af van uw toepassing.

Beschouw het volgende voorbeeld van een matrix C met complexe getallen:

>> C = [1i, 2; 3*1i, 4]
C =
   0.0000 + 1.0000i   2.0000 + 0.0000i
   0.0000 + 3.0000i   4.0000 + 0.0000i

Laten we het transponeren met behulp van de steno .' (met de punt). De output is zoals verwacht, de getransponeerde vorm van C

>> C.'
ans =
   0.0000 + 1.0000i   0.0000 + 3.0000i
   2.0000 + 0.0000i   4.0000 + 0.0000i

Laten we nu gebruiken ' (zonder de punt). We zien dat, naast de transpositie, de complexe waarden ook zijn omgezet in hun complexe conjugaten .

>> C'
ans =
   0.0000 - 1.0000i   0.0000 - 3.0000i
   2.0000 + 0.0000i   4.0000 + 0.0000i

Samenvattend, als u van plan bent het Hermitische conjugaat te berekenen, het complexe geconjugeerde transponeren, gebruik dan ' (zonder de punt). Als u alleen de transponering wilt berekenen zonder de waarden ingewikkeld te vervoegen, gebruikt u .' (met de punt).

Ongedefinieerde functie of methode X voor invoerargumenten van type Y

Dit is de langdradige manier van MATLAB om te zeggen dat het de functie niet kan vinden die u probeert aan te roepen. Er zijn een aantal redenen waarom u deze fout kunt krijgen:

Die functie is geïntroduceerd na uw huidige versie van MATLAB

De online documentatie van MATLAB biedt een zeer mooie functie waarmee u kunt bepalen in welke versie een bepaalde functie is geïntroduceerd. Deze bevindt zich links onderaan elke pagina van de documentatie:

voer hier de afbeeldingsbeschrijving in

Vergelijk deze versie met uw eigen huidige versie ( ver ) om te bepalen of deze functie beschikbaar is in uw specifieke versie. Als dit niet het geval is, probeer dan in de gearchiveerde versies van de documentatie te zoeken naar een geschikt alternatief in uw versie.

Je hebt die toolbox niet!

De basis MATLAB-installatie heeft een groot aantal functies; meer gespecialiseerde functionaliteit is echter verpakt in gereedschapskisten en wordt apart verkocht door Mathworks. De documentatie voor alle gereedschapskisten is zichtbaar, of u de gereedschapskist hebt of niet, dus controleer of u de juiste gereedschapskist hebt.

Als u wilt controleren tot welke gereedschapskist een bepaalde functie behoort, kijkt u linksboven in de online documentatie om te zien of een specifieke gereedschapskist wordt vermeld.

voer hier de afbeeldingsbeschrijving in

U kunt vervolgens bepalen welke toolboxen uw versie van MATLAB heeft geïnstalleerd door de opdracht ver waarmee een lijst van alle geïnstalleerde toolboxen wordt afgedrukt.

Als u die toolbox niet hebt geïnstalleerd en de functie wilt gebruiken, moet u een licentie kopen voor die specifieke toolbox van The Mathworks.

MATLAB kan de functie niet vinden

Als MATLAB uw functie nog steeds niet kan vinden, moet het een door de gebruiker gedefinieerde functie zijn. Het is mogelijk dat deze in een andere map staat en dat die map moet worden toegevoegd aan het zoekpad zodat uw code kan worden uitgevoerd. U kunt controleren of MATLAB uw functie kan vinden met behulp van which het pad naar het bronbestand moet retourneren.

Let op drijvende komma onnauwkeurigheid

Drijvende-kommagetallen kunnen niet alle reële getallen vertegenwoordigen. Dit staat bekend als drijvende komma-onnauwkeurigheid.

Er zijn oneindig veel drijvende-kommagetallen en ze kunnen oneindig lang zijn (bijv. π ), dus om ze perfect te kunnen representeren zou oneindig veel geheugen nodig zijn. Omdat dit een probleem was, werd een speciale weergave voor "echte nummer" -opslag op de computer ontworpen, de IEEE 754-standaard . Kortom, het beschrijft hoe computers dit soort nummers opslaan, met een exponent en mantisse, als,

floatnum = sign * 2^exponent * mantissa

Met een beperkt aantal bits voor elk van deze, kan slechts een eindige precisie worden bereikt. Hoe kleiner het nummer, hoe kleiner de kloof tussen mogelijke nummers (en vice versa!). Je kunt je echte getallen proberen in deze online demo .

Wees je bewust van dit gedrag en probeer alle vergelijking van drijvende punten en hun gebruik als stopomstandigheden in lussen te vermijden. Zie hieronder twee voorbeelden:

Voorbeelden: vergelijking van drijvende komma verkeerd.

>> 0.1 + 0.1 + 0.1  == 0.3

ans =

  logical

   0

Het is een slechte gewoonte om een zwevende puntvergelijking te gebruiken, zoals blijkt uit het voorgaande voorbeeld. Je kunt het overwinnen door de absolute waarde van hun verschil te nemen en het te vergelijken met een (klein) tolerantieniveau.

Hieronder is een ander voorbeeld, waarbij een drijvende-kommagetal wordt gebruikt als stopvoorwaarde in een while-lus: **

k = 0.1;
while k <= 0.3 
  disp(num2str(k));
  k = k + 0.1;
end

% --- Output: ---
0.1
0.2

Het mist de laatst verwachte lus ( 0.3 <= 0.3 ).

Voorbeeld: vergelijking van drijvende komma RECHTS:

x = 0.1 + 0.1 + 0.1;
y = 0.3;
tolerance = 1e-10; % A "good enough" tolerance for this case.

if ( abs( x - y ) <= tolerance )
  disp('x == y');
else
  disp('x ~= y');
end

% --- Output: ---
x == y

Verschillende dingen om op te merken:

  • Zoals verwacht, worden nu x en y als gelijkwaardig behandeld.
  • In het bovenstaande voorbeeld werd de keuze van de tolerantie willekeurig gedaan. Het is dus mogelijk dat de gekozen waarde niet voor alle gevallen geschikt is (vooral als u met veel kleinere getallen werkt). Het intelligent kiezen van de binding kan worden gedaan met behulp van de eps functie, dat wil zeggen N*eps(max(x,y)) , waarbij N een probleemspecifiek nummer is. Een redelijke keuze voor N , die ook toelaatbaar is, is 1E2 (hoewel in het bovenstaande probleem ook N=1 voldoende zou zijn).

Verder lezen:

Bekijk deze vragen voor meer informatie over drijvende komma-onnauwkeurigheid:

niet genoeg inbrengende argumenten

Vaak beginnen beginnende MATLAB-ontwikkelaars met de editor van MATLAB om code te schrijven en te bewerken, met name aangepaste functies met in- en uitgangen. Er is een knop Uitvoeren bovenaan die beschikbaar is in recente versies van MATLAB:

voer hier de afbeeldingsbeschrijving in

Zodra de ontwikkelaar klaar is met de code, komen ze vaak in de verleiding om op de knop Uitvoeren te drukken. Voor sommige functies zal dit prima werken, maar voor anderen zullen ze een ontvangen Not enough input arguments fout en worden verbaasd over de reden waarom de fout optreedt.

De reden waarom deze fout mogelijk niet optreedt, is omdat u een MATLAB-script of een functie hebt geschreven die geen invoerargumenten bevat. Met de knop Uitvoeren wordt een testscript uitgevoerd of wordt een functie uitgevoerd zonder invoerargumenten. Als uw functie invoerargumenten vereist, zal de fout Not enough input arguments optreden omdat u een functie hebt geschreven die verwacht dat invoer binnen de functie gaat. Daarom kunt u niet verwachten dat de functie wordt uitgevoerd door eenvoudig op de knop Run te drukken.

Om dit probleem aan te tonen, stel dat we een functie mult die eenvoudigweg twee matrices samen vermenigvuldigt:

function C = mult(A, B)
    C = A * B;
end

Als je in recente versies van MATLAB deze functie hebt geschreven en op de knop Uitvoeren hebt gedrukt, krijg je de fout die we verwachten:

>> mult
Not enough input arguments.

Error in mult (line 2)
    C = A * B;

Er zijn twee manieren om dit probleem op te lossen:

Methode # 1 - Via de opdrachtprompt

Maak eenvoudig de ingangen die u nodig hebt in de opdrachtprompt en voer vervolgens de functie uit met de ingangen die u hebt gemaakt:

A = rand(5,5);
B = rand(5,5);
C = mult(A,B);

Methode # 2 - Interactief via de Editor

Onder de knop Uitvoeren bevindt zich een donkerzwarte pijl. Als u op die pijl klikt, kunt u de variabelen opgeven die u uit de MATLAB-werkruimte wilt halen door de manier te typen waarop u de functie wilt aanroepen, precies zoals u deze hebt gezien in methode # 1. Zorg ervoor dat de variabelen die u opgeeft in de functie aanwezig zijn in de MATLAB-werkruimte:

Kijk uit voor wijzigingen in de array-grootte

Sommige veel voorkomende bewerkingen in MATLAB, zoals differentiatie of integratie , hebben resultaten die een andere hoeveelheid elementen hebben dan de invoergegevens. Dit feit kan gemakkelijk over het hoofd worden gezien, wat meestal fouten zoals Matrix dimensions must agree . Overweeg het volgende voorbeeld:

t = 0:0.1:10;        % Declaring a time vector
y = sin(t);          % Declaring a function

dy_dt = diff(y);     % calculates dy/dt for y = sin(t)

Laten we zeggen dat we deze resultaten willen plotten. We bekijken de matrixgroottes en zien:

size(y) is 1x101
size(t) is 1x101

Maar:

size(dy_dt) is 1x100

De array is één element korter!

Stel je nu voor dat je meetgegevens van posities in de tijd hebt en schok (t) wilt berekenen, je krijgt een array 3 elementen minder dan de tijdarray (omdat de schok de positie 3 keer is gedifferentieerd).

vel = diff(y);       % calculates velocity vel=dy/dt for y = sin(t)  size(vel)=1x100
acc = diff(vel);     % calculates acceleration acc=d(vel)/dt         size(acc)=1x99
jerk = diff(acc);    % calculates jerk jerk=d(acc)/dt                size(jerk)=1x98   

En dan operaties zoals:

x = jerk .* t;          % multiplies jerk and t element wise

retourneer fouten, omdat de matrixafmetingen niet overeenkomen.

Om bewerkingen zoals hierboven te berekenen, moet u de grotere matrixgrootte aanpassen aan de kleinere. U kunt ook een regressie ( polyfit ) uitvoeren met uw gegevens om een polynoom voor uw gegevens te krijgen.

Foutieve dimensiefouten

Foutieve dimensiefouten verschijnen meestal wanneer:

  • Geen aandacht besteden aan de vorm van geretourneerde variabelen uit functie- / methode-aanroepen. In veel ingebouwde MATLAB-functies worden matrices omgezet in vectoren om de berekeningen te versnellen, en de geretourneerde variabele kan nog steeds een vector zijn in plaats van de matrix die we hadden verwacht. Dit is ook een veel voorkomend scenario als het gaat om logische maskering .
  • Het gebruik van incompatibele arraygroottes terwijl een impliciete array-uitbreiding wordt aangeroepen .

Het gebruik van "i" of "j" als imaginaire eenheid, lusindices of gemeenschappelijke variabele.

Aanbeveling

Omdat de symbolen i en j aanzienlijk verschillende dingen in MATLAB kunnen vertegenwoordigen, heeft het gebruik ervan als lusindices de MATLAB-gebruikersgemeenschap al eeuwen verdeeld. Hoewel sommige historische prestatieredenen de balans naar één kant kunnen helpen leunen, is dit niet langer het geval en nu ligt de keuze volledig bij jou en de codeermethoden die je kiest te volgen.

De huidige officiële aanbevelingen van Mathworks zijn:

  • Aangezien i een functie is, kan deze worden genegeerd en als variabele worden gebruikt. Het is echter het beste om het gebruik van i en j voor variabelenamen te vermijden als u van plan bent ze in complexe rekenkunde te gebruiken.
  • Gebruik 1i en 1j plaats van i en j voor snelheid en verbeterde robuustheid in complexe rekenkunde.

Standaard

In MATLAB zijn de letters i en j standaard ingebouwde function , die beide verwijzen naar de imaginaire eenheid in het complexe domein.

Dus standaard i = j = sqrt(-1) .

>> i
ans =
   0.0000 + 1.0000i
>> j
ans =
   0.0000 + 1.0000i

en zoals je zou verwachten:

>> i^2
ans =
    -1

Gebruik ze als variabele (voor lusindexen of andere variabele)

Met MATLAB kan de ingebouwde functienaam als standaardvariabele worden gebruikt. In dit geval verwijst het gebruikte symbool niet meer naar de ingebouwde functie, maar naar uw eigen door de gebruiker gedefinieerde variabele. Deze praktijk wordt echter over het algemeen niet aanbevolen, omdat dit kan leiden tot verwarring, moeilijk opsporen en onderhoud ( zie ander voorbeeld doe-geen-naam-een-variabele-met-een-bestaande-functienaam ).

Als je ultra pedant bent over het respecteren van conventies en best practices, vermijd je ze te gebruiken als lusindices in deze taal. Het is echter toegestaan door de compiler en perfect functioneel, dus je kunt er ook voor kiezen om oude gewoonten te behouden en ze te gebruiken als lus-iterators.

>> A = nan(2,3);
>> for i=1:2        % perfectly legal loop construction
       for j = 1:3
        A(i, j) = 10 * i + j;
       end
   end

Merk op dat lusindices niet buiten het bereik van de lus vallen, zodat ze hun nieuwe waarde behouden.

>> [ i ; j ]
ans =
     2
     3

In het geval u ze als variabele gebruikt, moet u ervoor zorgen dat ze worden geïnitialiseerd voordat ze worden gebruikt. In de bovenstaande lus initialiseert MATLAB ze automatisch bij het voorbereiden van de lus, maar als ze niet correct worden geïnitialiseerd, kunt u snel zien dat u per ongeluk complex getallen in uw resultaat invoert.

Als u later de schaduw van de ingebouwde functie ongedaan wilt maken (= u wilt bijvoorbeeld dat i en j de imaginaire eenheid opnieuw vertegenwoordigen), kunt u de variabelen clear :

>> clear i j

U begrijpt nu het voorbehoud van Mathworks over het gebruik ervan als lusindexen als u van plan bent ze in complexe rekenkunde te gebruiken . Uw code zou worden bezaaid met variabele initialisaties en clear commando's, de beste manier om de meest serieuze programmeur ( ja u daar! ... ) te verwarren en programma-ongelukken te wachten.

Als er geen complexe rekenkunde wordt verwacht, is het gebruik van i en j perfect functioneel en is er geen prestatieverlies.


Gebruik ze als een denkbeeldige eenheid:

Als uw code te maken heeft met complex getallen, komen i en j zeker van pas. Omwille van ondubbelzinnigheid en zelfs voor uitvoeringen, wordt echter aanbevolen om de volledige vorm te gebruiken in plaats van de steno-syntaxis. De volledige vorm is 1i (of 1j ).

>> [ i ; j ; 1i ; 1j]
ans =
   0.0000 + 1.0000i
   0.0000 + 1.0000i
   0.0000 + 1.0000i
   0.0000 + 1.0000i

Ze vertegenwoordigen dezelfde waarde sqrt(-1) , maar de latere vorm:

  • is meer expliciet, op een semantische manier.
  • is beter te onderhouden (iemand die uw code later bekijkt, hoeft de code niet te lezen om te bepalen of i of j een variabele of de denkbeeldige eenheid was).
  • is sneller (bron: Mathworks).

Merk op dat de volledige syntaxis 1i geldig is met elk nummer voorafgaand aan het symbool:

>> a = 3 + 7.8j
a =
   3.0000 + 7.8000i

Dit is de enige functie die u bij een nummer kunt houden zonder een operator ertussen.


valkuilen

Hoewel hun gebruik als denkbeeldige eenheid OF variabele volkomen legaal is, is hier slechts een klein voorbeeld van hoe verwarrend het zou kunnen zijn als beide gebruiken gemengd worden:

Laten we i overschrijven en er een variabele van maken:

>> i=3
i =
     3

Nu is i een variabele (met de waarde 3 ), maar we overschrijven alleen de steno- notatie van de denkbeeldige eenheid, de volledige vorm wordt nog steeds correct geïnterpreteerd:

>> 3i
ans =
   0.0000 + 3.0000i

Hiermee kunnen we nu de meest obscure formuleringen maken. Ik laat u de leesbaarheid van alle volgende constructies beoordelen:

>> [ i ; 3i ; 3*i ; i+3i ; i+3*i ]
ans =
   3.0000 + 0.0000i
   0.0000 + 3.0000i
   9.0000 + 0.0000i
   3.0000 + 3.0000i
  12.0000 + 0.0000i

Zoals u ziet, retourneert elke waarde in de bovenstaande matrix een ander resultaat. Hoewel elk resultaat geldig is (op voorwaarde dat dit de oorspronkelijke bedoeling was), zullen de meesten van jullie toegeven dat het een behoorlijke nachtmerrie zou zijn om een code te lezen vol met dergelijke constructies.

Het gebruik van `lengte` voor multidimensionale arrays

Een veel voorkomende fout die MATLAB-coders hebben, is het gebruik van de length voor matrices (in tegenstelling tot vectoren waarvoor het is bedoeld). De length , zoals vermeld in de documentatie , " retourneert de lengte van de grootste matrixdimensie " van de invoer.

Voor vectoren heeft de retourwaarde van length twee verschillende betekenissen:

  1. Het totale aantal elementen in de vector.
  2. De grootste dimensie van de vector.

Anders dan in vectoren, zouden de bovenstaande waarden niet gelijk zijn voor arrays met meer dan één niet-singleton (dwz waarvan de grootte groter is dan 1 ). Daarom is het gebruik van length voor matrices dubbelzinnig. In plaats daarvan wordt het gebruik van een van de volgende functies aangemoedigd, zelfs bij het werken met vectoren, om de bedoeling van de code volkomen duidelijk te maken:

  1. size(A) - geeft een rijvector terug waarvan de elementen het aantal elementen bevatten langs de overeenkomstige dimensie van A
  2. numel(A) - geeft het aantal elementen in A . Gelijk aan prod(size(A)) .
  3. ndims(A) - geeft het aantal dimensies in de array A . Gelijk aan numel(size(A)) .

Dit is vooral belangrijk bij het schrijven van "toekomstbestendige", gevectoriseerde bibliotheekfuncties, waarvan de invoer niet van tevoren bekend is en die verschillende afmetingen en vormen kunnen hebben.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow