Sök…


Namnge inte en variabel med ett befintligt funktionsnamn

Det finns redan en funktionssumma sum() . Som ett resultat, om vi namnger en variabel med samma namn

sum = 1+3;

och om vi försöker använda funktionen medan variabeln fortfarande finns i arbetsområdet

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

vi får det kryptiska felet :

Subscript indices must either be real positive integers or logicals.

clear() variabeln och använd sedan funktionen

clear sum

sum(A,1)
ans =
       1.0826       1.0279

Hur kan vi kontrollera om det redan finns en funktion för att undvika denna konflikt?

Använd which() med -all flaggan:

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

Denna utgång berättar för oss att sum först är en variabel och att följande metoder (funktioner) är skuggade av den, dvs. MATLAB kommer först att försöka tillämpa vår syntax på variabeln snarare än att använda metoden.

Vad du ser är INTE vad du får: char vs cellstring i kommandofönstret

Detta är ett grundläggande exempel riktat mot nya användare. Det fokuserar inte på att förklara skillnaden mellan char och cellstring .


Det kan hända att du vill bli av med ' i dina strängar, även om du aldrig har lagt till dem. Det är faktiskt artefakter som kommandofönstret använder för att skilja mellan vissa typer.

En sträng skrivs ut

s = 'dsadasd'
s =
dsadasd

En cellsträng kommer att skrivas ut

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

Lägg märke till hur enstaka citat och indragning är artefakter för att meddela oss att c är en cellstring snarare än en char . Strängen finns faktiskt i cellen, dvs.

c{1}
ans =
dsadasd

Transponeringsoperatörerna

  • .' är det rätta sättet att transponera en vektor eller matris i MATLAB.
  • ' är det rätta sättet att ta den komplexa konjugattransponeringen (aka Hermitisk konjugat) av en vektor eller matris i MATLAB.

Observera att för transponering .' , det finns en period framför apostrofen. Detta överensstämmer med syntaxen för de andra elementvisa operationerna i MATLAB: * multiplicerar matriser,. .* Multiplicerar element av matriser tillsammans. De två kommandona är mycket lika, men konceptuellt mycket distinkta. Liksom andra MATLAB-kommandon är dessa operatörer "syntaktiskt socker" som förvandlas till ett "korrekt" funktionssamtal vid körning. Precis som == blir en utvärdering av eq- funktionen, tänk på .' som kortfattat för transpose . Om du bara skulle skriva ' (utan ctranspose använder du i själva verket ctranspose kommandot istället, vilket beräknar den komplexa konjugattransposen , som också kallas den hermitiska konjugaten , som ofta används i fysiken. Så länge den transponerade vektorn eller matrisen verkligt värderas ger de två operatörerna samma resultat. Men så snart vi hanterar komplexa siffror kommer vi oundvikligen att stöta på problem om vi inte använder den "korrekta" korthaven. Vad "rätt" är beror på din ansökan.

Tänk på följande exempel på en matris C innehåller komplexa siffror:

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

Låt oss ta transponering med hjälp av korthaven .' (med perioden). Utgången är som förväntat, den transponerade formen av C

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

Nu ska vi använda ' (utan perioden). Vi ser att de komplicerade värdena förutom införlivandet har omvandlats till deras komplexa konjugat också.

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

Sammanfattningsvis, om du tänker beräkna det hermitiska konjugatet, transponerar det komplexa konjugatet, använd sedan ' (utan perioden). Om du bara vill beräkna transponera utan att konjugera värdena, använd .' (med perioden).

Odefinierad funktion eller metod X för inmatningsargument av typ Y

Detta är MATLABs långvariga sätt att säga att den inte kan hitta den funktion du försöker ringa. Det finns flera orsaker till att du kan få detta fel:

Denna funktion introducerades efter din nuvarande version av MATLAB

MATLAB online-dokumentation ger en mycket trevlig funktion som låter dig bestämma i vilken version en given funktion introducerades. Det finns längst ner till vänster på varje sida i dokumentationen:

ange bildbeskrivning här

Jämför den här versionen med din egen aktuella version ( ver ) för att avgöra om den här funktionen är tillgänglig i din specifika version. Om det inte är det, kan du försöka söka i de arkiverade versionerna av dokumentationen för att hitta ett lämpligt alternativ i din version.

Du har inte den verktygslådan!

MATLAB-basinstallationen har ett stort antal funktioner; mer specialiserad funktionalitet förpackas dock i verktygslådor och säljs separat av Mathworks. Dokumentationen för alla verktygslådor är synlig oavsett om du har verktygslådan eller inte, så se till om du har rätt verktygslåda.

För att kontrollera vilken verktygslåda en viss funktion tillhör, titta längst upp till vänster i online-dokumentationen för att se om en specifik verktygslåda nämns.

ange bildbeskrivning här

Du kan sedan bestämma vilka verktygslådor din version av MATLAB har installerat genom att utfärda ver kommandot som kommer att skriva ut en lista över alla installerade verktygslådor.

Om du inte har den verktygslådan installerad och vill använda funktionen måste du köpa en licens för den specifika verktygslådan från The Mathworks.

MATLAB kan inte hitta funktionen

Om MATLAB fortfarande inte kan hitta din funktion, måste den vara en användardefinierad funktion. Det är möjligt att den lever i en annan katalog och att katalogen ska läggas till i sökvägen för din kod att köra. Du kan kontrollera om MATLAB kan hitta din funktion genom att använda which som ska returnera sökvägen till källfilen.

Var medveten om flytande punktens felaktighet

Flyttalsnummer kan inte representera alla verkliga siffror. Detta är känt som flytande punktens felaktighet.

Det finns oändligt många flytande punktsnummer och de kan vara oändligt långa (t.ex. π ), och för att kunna representera dem perfekt skulle det kräva oändligt mycket minne. Att se detta var ett problem, en speciell representation för "riktigt antal" lagring i dator designades, IEEE 754-standarden . Kort sagt, den beskriver hur datorer lagrar denna typ av nummer, med en exponent och mantissa, som,

floatnum = sign * 2^exponent * mantissa

Med begränsad mängd bitar för var och en av dessa kan endast en ändlig precision uppnås. Ju mindre antal, desto mindre skillnad mellan möjliga nummer (och vice versa!). Du kan prova dina riktiga siffror i den här online-demonstrationen .

Var medveten om detta beteende och försök att undvika all jämförelse av flytande punkter och deras användning som stoppförhållanden i öglor. Se två exempel nedan:

Exempel: Jämförelse av flytande punkter gjort FEL:

>> 0.1 + 0.1 + 0.1  == 0.3

ans =

  logical

   0

Det är dålig praxis att använda flyttalsjämförelse som visas i föregående exempel. Du kan övervinna den genom att ta det absoluta värdet på deras skillnad och jämföra det med en (liten) toleransnivå.

Nedan är ett annat exempel, där ett flytande punktnummer används som stoppvillkor i en stundslinga: **

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

% --- Output: ---
0.1
0.2

Den saknar den senaste förväntade slingan ( 0.3 <= 0.3 ).

Exempel: Jämförelse av flytande punkt gjort HÖGER:

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

Flera saker att notera:

  • Som förväntat behandlas nu x och y som likvärdiga.
  • I exemplet ovan gjordes valet av tolerans godtyckligt. Således kanske det valda värdet inte är lämpligt för alla fall (särskilt när du arbetar med mycket mindre antal). Att välja det bundna intelligent kan göras med hjälp av eps funktionen, dvs N*eps(max(x,y)) , där N är något problemspecifikt nummer. Ett rimligt val för N , som också är tillåtet tillräckligt, är 1E2 (även om i ovanstående problem N=1 skulle räcka).

Vidare läsning:

Se dessa frågor för mer information om flytande punktens felaktighet:

Inte tillräckligt med inmatningsargument

Ofta börjar MATLAB-utvecklare använda MATLABs redaktör för att skriva och redigera kod, i synnerhet anpassade funktioner med in- och utgångar. Det finns en Kör- knapp överst som är tillgänglig i de senaste versionerna av MATLAB:

ange bildbeskrivning här

När utvecklaren är klar med koden frestas de ofta att trycka på knappen Kör . För vissa funktioner fungerar detta bra, men för andra får de ett fel som Not enough input arguments och förundras över varför felet inträffar.

Anledningen till att det här felet kanske inte händer är att du skrev ett MATLAB-skript eller en funktion som inte tar några inmatningsargument. Med hjälp av Kör- knappen körs ett testskript eller kör en funktion förutsatt att inga inmatningsargument finns. Om din funktion kräver inmatningsargument uppstår felet Not enough input arguments eftersom du har skrivit en funktion som förväntar sig att ingångar ska gå in i funktionen. Därför kan du inte förvänta dig att funktionen ska köras genom att bara trycka på Kör- knappen.

För att demonstrera detta problem, antar att vi har en funktion mult som helt enkelt multiplicerar två matriser tillsammans:

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

I de senaste versionerna av MATLAB, om du skrev den här funktionen och tryckte på Run- knappen, kommer det att ge dig det fel vi förväntar oss:

>> mult
Not enough input arguments.

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

Det finns två sätt att lösa problemet:

Metod # 1 - Genom kommandotolken

Skapa helt enkelt de ingångar du behöver i kommandotolken och kör sedan funktionen med de ingångar du har skapat:

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

Metod # 2 - Interaktivt genom redaktören

Under knappen Kör finns en mörk svart pil. Om du klickar på den pilen kan du ange de variabler du vill få från MATLAB-arbetsområdet genom att skriva det sätt du vill kalla funktionen exakt som du har sett i metod # 1. Se till att variablerna som du anger i funktionen finns i MATLAB-arbetsområdet:

Se upp för ändringar i matrisstorlek

Vissa vanliga operationer i MATLAB, som differentiering eller integration , ger resultat som har en annan mängd element än inputdata. Detta faktum kan lätt förbises, vilket vanligtvis skulle orsaka fel som Matrix dimensions must agree . Tänk på följande exempel:

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)

Låt oss säga att vi vill plotta dessa resultat. Vi tittar på matrisstorlekarna och ser:

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

Men:

size(dy_dt) is 1x100

Arrayen är ett element kortare!

Föreställ dig nu att du har mätdata för positioner över tid och vill beräkna skämt (t) , du kommer att få en grupp 3 element mindre än tidsuppsättningen (eftersom skiten är den position som är differentierad 3 gånger).

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   

Och sedan operationer som:

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

returnera fel, eftersom matrisdimensionerna inte är överens.

För att beräkna operationer som ovan måste du justera den större matrisstorleken så att den passar den mindre. Du kan också köra en regression ( polyfit ) med dina data för att få ett polynom för dina data.

Dimension Mismatch-fel

Fel i dimensionens anpassning visas vanligtvis när:

  • Observera inte formen på returnerade variabler från funktions- / metodsamtal. I många inbyggda MATLAB-funktioner konverteras matriser till vektorer för att påskynda beräkningarna, och den returnerade variabeln kan fortfarande vara en vektor snarare än den matris som vi förväntade oss. Detta är också ett vanligt scenario när logisk maskering är involverad.
  • Använda inkompatibla matrisstorlekar medan man åberopar implicit array-expansion .

Användningen av "i" eller "j" som imaginär enhet, loopindex eller vanlig variabel.

Rekommendation

Eftersom symbolerna i och j kan representera betydligt olika saker i MATLAB, har deras användning som slingindex delat MATLAB-användargemenskapen sedan åldrar. Medan vissa historiska skäl kan hjälpa balansen att luta sig åt en sida, är detta inte längre fallet och nu ligger valet helt på dig och de kodningssätt som du väljer att följa.

De nuvarande officiella rekommendationerna från Mathworks är:

  • Eftersom i är en funktion kan den åsidosättas och användas som en variabel. Det är dock bäst att undvika att använda i och j för variabla namn om du tänker använda dem i komplex aritmetik.
  • 1i och 1j istället för i och j för snabbhet och förbättrad robusthet i komplex aritmetik.

Standard

I MATLAB är som standard bokstäverna i och j inbyggda function , som båda hänvisar till den imaginära enheten i den komplexa domänen.

Så som standard är i = j = sqrt(-1) .

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

och som du kan förvänta dig:

>> i^2
ans =
    -1

Använda dem som en variabel (för loopindex eller annan variabel)

MATLAB tillåter användning av inbyggt funktionsnamn som en standardvariabel. I detta fall pekar den använda symbolen inte längre till den inbyggda funktionen utan till din egen användardefinierade variabel. Denna praxis rekommenderas emellertid inte i allmänhet eftersom den kan leda till förvirring, svår felsökning och underhåll ( se andra exempel gör inte-namn-en-variabel-med-ett-befintligt-funktion-namn ).

Om du är extremt pedantisk när det gäller att respektera konventioner och bästa praxis kommer du att undvika att använda dem som slingindex på detta språk. Det är dock tillåtet av kompilatorn och perfekt funktionellt, så du kan också välja att behålla gamla vanor och använda dem som loop iteratorer.

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

Observera att slingindex inte går utanför räckvidden i slutet av slingan, så de behåller sitt nya värde.

>> [ i ; j ]
ans =
     2
     3

Om du använder dem som variabel, se till att de initialiseras innan de används. I slingan ovan initialiserar MATLAB dem automatiskt när den förbereder slingan, men om den inte initialiseras korrekt kan du snabbt se att du oavsiktligt kan införa complex siffror i ditt resultat.

Om du senare måste ångra skuggningen av den inbyggda funktionen (= t.ex. vill du att i och j ska representera den imaginära enheten igen) kan du clear variablerna:

>> clear i j

Du förstår nu Mathworks-reservationen om att använda dem som slingindex om du tänker använda dem i komplex aritmetik . Din kod skulle vara full av variabla initialiseringar och clear kommandon, bästa sättet att förvirra den allvarligaste programmeraren ( ja du där! ... ) och programolyckor som väntar på att hända.

Om ingen komplex aritmetik förväntas är användningen av i och j perfekt funktionell och det finns ingen prestationsstraff.


Använda dem som imaginär enhet:

Om din kod måste hantera complex nummer kommer i och j säkert att vara praktiska. För disambiguation och till och med för föreställningar rekommenderas det dock att använda den fullständiga formen i stället för den korta syntaxen. Hela formuläret är 1i (eller 1j ).

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

De representerar samma värde sqrt(-1) , men den senare formen:

  • är mer uttryckligt på ett semantiskt sätt.
  • är mer underhållbar (någon som tittar på din kod senare behöver inte läsa upp koden för att hitta om i eller j var en variabel eller den imaginära enheten).
  • är snabbare (källa: Mathworks).

Observera att hela syntaxen 1i är giltig med valfritt nummer före symbolen:

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

Detta är den enda funktionen som du kan hålla fast vid ett nummer utan en operatör mellan dem.


Fallgropar gropar~~POS=HEADCOMP

Även om deras användning som imaginär enhet ELLER variabel är helt laglig, är här bara ett litet exempel på hur förvirrande det kan bli om båda användningarna blir blandade:

Låt oss åsidosätta i och göra det till en variabel:

>> i=3
i =
     3

Nu är i en variabel (innehar värdet 3 ), men vi överbryter bara den korta notationen för den imaginära enheten, hela formen tolkas fortfarande korrekt:

>> 3i
ans =
   0.0000 + 3.0000i

Som nu låter oss bygga de mest otydliga formuleringarna. Jag låter dig bedöma läsbarheten för alla följande konstruktioner:

>> [ 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

Som ni ser ger varje värde i matchen ovan ett annat resultat. Samtidigt som varje resultat är giltigt (förutsatt att det var den ursprungliga avsikten), kommer de flesta av er att erkänna att det skulle vara en riktig mardröm att läsa en kod full av sådana konstruktioner.

Använda "längd" för flerdimensionella matriser

Ett vanligt misstag MATLAB kodare har, använder length funktion för matriser (i motsats till vektorer, för vilken den är avsedd). Den length -funktionen, som nämns i dess dokumentation , "returnerar längden av den största uppsättningen dimensionen" av insignalen.

För vektorer har returvärdet för length två olika betydelser:

  1. Det totala antalet element i vektorn.
  2. Den största dimensionen av vektorn.

Till skillnad från i vektorer, skulle ovanstående värden inte vara lika för matriser med mer än en icke-singleton (dvs. vars storlek är större än 1 ). Därför är det tvetydigt att använda length för matriser. Istället uppmanas att använda en av följande funktioner, även när man arbetar med vektorer, för att göra avsikten med koden helt klar:

  1. size(A) - returnerar en radvektor vars element innehåller mängden element längs motsvarande dimension av A
  2. numel(A) - returnerar antalet element i A Motsvarande med prod(size(A)) .
  3. ndims(A) - returnerar antalet dimensioner i matchen A Motsvarande med numel(size(A)) .

Detta är särskilt viktigt när du skriver "framtidssäkra", vektoriserade biblioteksfunktioner, vars ingångar inte är kända i förväg och kan ha olika storlekar och former.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow