Vectoren en matrices
Een vector is een vlakke getallenlijst, zoals een richting in de ruimte of een reeks hoeveelheden. Een matrix is een lijst van rijen. Deze pagina behandelt inwendig en uitwendig product, matrixvermenigvuldiging, determinanten en inversen, lineaire stelsels oplossen en numerieke lineaire algebra: eigenwaarden en QR-, LU- en singulierewaardendecompositie.
Gebruik dit voor lineaire algebra, meetkunde en transformaties, of problemen met meerdere onbekenden gekoppeld door lineaire vergelijkingen. Vectoren en matrices zijn gewone lijsten; alles bij Lijsten en statistiek, zoals indexeren, geldt dus ook.
Vectoren
dot([1, 2, 3], [4, 5, 6]) geeft 32dot([3, 4], [4, -3]) geeft 0cross([1, 0, 0], [0, 1, 0]) geeft [0, 0, 1]cross([1, 2, 3], [4, 5, 6]) geeft [-3, 6, -3]v = [3, 4]sqrt(dot(v, v)) geeft 5dot vermenigvuldigt overeenkomstige elementen en telt de producten op. Een inwendig product nul betekent dat de vectoren loodrecht staan, zoals [3, 4] en [4, -3]. cross geeft een vector loodrecht op beide invoervectoren: de x-richting uitwendig vermenigvuldigd met de y-richting geeft de z-richting. De vectorlengte is de vierkantswortel van het inwendig product met zichzelf.
dot vereist twee even lange vectoren; cross twee vectoren van drie elementen. Gebruik gewone lijstbewerkingen om vectoren op te tellen of te schalen: [1, 2] + [3, 4] is [4, 6] en 2 * [3, 4] is [6, 8].
Matrices schrijven en vermenigvuldigen
Schrijf een matrix als lijst van rijen, elke rij tussen eigen vierkante haken:
shape([[1, 2, 3], [4, 5, 6]]) geeft [2, 3]transpose([[1, 2, 3], [4, 5, 6]]) geeft [[1, 4], [2, 5], [3, 6]]identity(3) geeft [[1, 0, 0], [0, 1, 0], [0, 0, 1]][[1, 2], [3, 4]] * [[5, 6], [7, 8]] geeft [[19, 22], [43, 50]]shape geeft [rows, columns]. transpose wisselt rijen en kolommen. identity(n) is de n bij n eenheidsmatrix die een andere matrix bij vermenigvuldigen ongewijzigd laat.
* tussen twee matrices is matrixvermenigvuldiging. Het aantal kolommen links moet gelijk zijn aan het aantal rijen rechts. Schrijf een vector als kolom, één element per rij, om een matrix met die vector te vermenigvuldigen:
# Rotate the point (3, 1) by 90° anticlockwiserotate = [[0, -1], [1, 0]]rotate * [[3], [1]] geeft [[-1], [3]]rotate * rotate geeft [[-1, 0], [0, -1]]Tweemaal 90° draaien is een halve draai. Daarom keert rotate * rotate beide tekens om. Een vlakke lijst zoals [3, 1] wordt rechts van een matrix niet geaccepteerd. Staat een vlakke lijst in een naam, dan maakt transpose([v]) er een kolom van.
Matrices van dezelfde vorm kun je optellen en aftrekken, en met een getal vermenigvuldigen of erdoor delen, net als andere lijsten.
Voor elke matrixbewerking gelden enkele regels:
- Elke rij moet evenveel elementen bevatten.
- Elementen moeten gewone getallen zijn. Eenheden en geld worden niet geaccepteerd.
- Een matrix mag maximaal 32 rijen en 32 kolommen hebben.
- Er is geen verkorte notatie met puntkomma’s. Schrijf
[[1, 2], [3, 4]], niet[1, 2; 3, 4].
Determinant, inverse, spoor en rang
M = [[2, 1], [5, 3]]det(M) geeft 1inverse(M) geeft [[3, -1], [-5, 2]]M * inverse(M) geeft [[1, 0], [0, 1]]trace(M) geeft 5inverse([[2, 1], [1, 3]]) geeft [[0.6, -0.2], [-0.2, 0.4]]det([[1, 2], [2, 4]]) geeft 0rank([[1, 2, 3], [2, 4, 6]]) geeft 1det, inverse en trace (de som van de diagonaal) vereisen een vierkante matrix. Een determinant nul betekent dat de matrix singulier is: de rijen zijn niet onafhankelijk en er is geen inverse. inverse([[1, 2], [2, 4]]) geeft dus een fout. rank telt onafhankelijke rijen en accepteert ook niet-vierkante matrices. In de laatste regel is rij twee het dubbele van rij één, dus de rang is 1.
Deze vier gebruiken exacte breuken in plaats van decimalen. Daarom geeft M * inverse(M) exact de eenheidsmatrix.
Een lineair stelsel oplossen
Stel dat drie koffies en twee theeën £13,50 kosten, en één koffie met vier theeën £11,50. Zet per vergelijking de aantallen drankjes in een rij, met vaste kolomvolgorde (koffie, thee), en de totalen in een overeenkomstige lijst:
solve_system([[3, 2], [1, 4]], [13.5, 11.5]) geeft [3.1, 2.1]Het resultaat volgt de kolomvolgorde: koffie kost £3,10 en thee £2,10. Laat valutatekens weg, omdat matrixelementen gewone getallen moeten zijn.
solve_system(A, b) lost A * x = b op voor x. Het vereist een vierkante matrix, één rij per onbekende, en een even lange vlakke lijst rechterleden. Het gebruikt exacte breuken, dus zonder afrondingsfout.
Bepalen de vergelijkingen geen uniek resultaat, dan volgt een fout dat het stelsel geen unieke oplossing heeft. solve_system([[1, 2], [2, 4]], [3, 6]) mislukt bijvoorbeeld omdat vergelijking twee het dubbele van de eerste is. solve_system behandelt alleen lineaire vergelijkingen. Gebruik voor bijvoorbeeld x^2 = 2 de functie solve uit Sommatie, vergelijkingen en calculus.
Eigenwaarden
eigenvalues([[2, 1], [1, 2]]) geeft [1, 3]eigenvalues([[4, 1], [2, 3]]) geeft [5, 2]eigenvalues([[0, -1], [1, 0]]) geeft [i, -i]eigenvalues neemt een vierkante matrix en geeft een vlakke lijst. Een rotatie van 90° behoudt geen richting, dus haar eigenwaarden zijn het complexe paar i en -i; zie Complexe getallen. Vertrouw niet op de lijstvolgorde.
Ontbindingen: QR, LU en SVD
Elke decompositie geeft een lijst matrices. Gebruik indexen om onderdelen eruit te halen:
A = [[3, 0], [4, 5]]parts = qr(A)q = parts[0] geeft [[0.6, -0.8], [0.8, 0.6]]r = parts[1] geeft [[5, 4], [0, 3]]q * r geeft [[3, 0], [4, 5]]De factoren terug vermenigvuldigen geeft weer A, zodat je de decompositie snel controleert. Binaire drijvendekommagetallen laten kleine afrondingsresten rond 10⁻¹⁵ achter; Varlig toont die in lijsten en matrices als 0. Opgeslagen waarden behouden alle cijfers. Vergelijk resultaten dus visueel of via hun verschil, niet met ==.
lu([[2, 1], [4, 3]]) geeft [[[0, 1], [1, 0]], [[1, 0], [0.5, 1]], [[4, 3], [0, -0.5]]]lu geeft [P, L, U]. P registreert rijwisselingen en P * A is gelijk aan L * U. Hier zijn de rijen verwisseld zodat het grotere getal, 4, eerst wordt gebruikt.
B = [[3, 1], [4, 7]]f = svd(B)u = f[0]s = f[1]vt = f[2]u * [[s[0], 0], [0, s[1]]] * vt geeft [[3, 1], [4, 7]]svd([[3, 4]]) geeft [[[1]], [5], [[0.6, 0.8]]]svd geeft [U, s, Vt], met s als vlakke lijst singuliere waarden, grootste eerst. In leerboeken is B gelijk aan U * diag(s) * Vt. Er is geen functie diag; bouw de diagonaalmatrix zelf, zoals [[s[0], 0], [0, s[1]]].
| Functie | Benodigde invoer en resultaat |
|---|---|
identity(n) |
De identiteitsmatrix van n bij n |
shape(A) |
[rows, columns] |
transpose(A) |
Rijen en kolommen verwisseld |
det(A) |
Determinant van een vierkante matrix |
inverse(A) |
Inverse van een vierkante matrix met een determinant ongelijk aan nul |
trace(A) |
Som van de hoofddiagonaal van een vierkante matrix |
rank(A) |
Aantal onafhankelijke rijen; elke rechthoekige matrix |
solve_system(A,b) |
Oplossing van A * x = b voor een vierkante matrix met één oplossing |
eigenvalues(A) |
Eigenwaarden van een vierkante matrix, mogelijk complex, zonder vaste volgorde |
qr(A) |
[Q, R] met Q * R ongeveer gelijk aan A; elke rechthoekige matrix |
lu(A) |
[P, L, U] met P * A ongeveer gelijk aan L * U; vierkante matrix |
svd(A) |
[U, s, Vt], waarbij s een vlakke lijst is; elke rechthoekige matrix |
Bij een niet-vierkante matrix geven qr en svd gereduceerde factoren. Voor een matrix van 3 bij 2 is Q ook 3 bij 2, niet 3 bij 3.
Wat exact is en wat wordt geweigerd
Matrices optellen, aftrekken en vermenigvuldigen, vermenigvuldiging met een getal, transpose, det en inverse gebruiken exacte breuken voor elke toegestane matrix. Niets wordt afgerond bij invoer of onderweg naar een volgende berekening. Daarom levert vermenigvuldigen met de inverse exact de eenheidsmatrix:
[[1, 2], [3, 4]] + [[10, 20], [30, 40]] geeft [[11, 22], [33, 44]][[1, 2], [3, 4]] - [[1, 1], [1, 1]] geeft [[0, 1], [2, 3]]3 * [[1, 2], [3, 4]] geeft [[3, 6], [9, 12]][[1, 2], [3, 4]] * [[0, 1], [1, 0]] geeft [[2, 1], [4, 3]]det([[1, 2], [3, 4]]) geeft -2inverse([[1, 2], [3, 4]]) geeft [[-2, 1], [1.5, -0.5]]inverse([[1, 2], [3, 4]]) * [[1, 2], [3, 4]] geeft [[1, 0], [0, 1]]Elke voorwaarde wordt gecontroleerd voordat een resultaat verschijnt; de melding benoemt welke niet klopt:
det([[1, 2, 3], [4, 5, 6]]) geeft Unsupported: Expected a square matrixinverse([[1, 2], [2, 4]]) geeft Unsupported: Singular matrix has no inverse[[1, 2], [3, 4]] + [[1, 2, 3], [4, 5, 6]] geeft Unsupported: List dimensions do not match[[1, 2, 3], [4, 5, 6]] * [[1, 2], [3, 4]] geeft Unsupported: Matrix inner dimensions do not matchMatrixelementen zijn gewone getallen. Een eenheid, geldbedrag of complexe waarde stopt de berekening in plaats van te worden meegenomen, omdat matrixbewerkingen die niet zouden behouden:
det([[1 kg, 2], [3, 4]]) geeft Unsupported: Matrix entries must be plain numbers; units, money and complex values are not supportedAlleen een lijst van rijen wordt als matrix gelezen. Een vlakke lijst behoudt haar betekenis: [1, 2] + [3, 4] blijft per element [4, 6]; [1, 2] * [3, 4] blijft een fout die naar dot verwijst.
Zie Wat de rekenengine garandeert voor alle exactheidsregels bij vergelijkingen, matrices en statistiek.
Algoritmen en limieten
det, inverse, rank en solve_system gebruiken exacte breuken binnen de grenzen voor getalgrootte. eigenvalues, qr, lu en svd gebruiken binaire drijvendekommagetallen en geven nauwkeurige benaderingen. Hun iteraties stoppen na 10.000 stappen.
Matrices met bijna afhankelijke rijen, zoals [[1, 1], [1, 1.0000001]], heten slecht geconditioneerd. Kleine afrondingsfouten kunnen sterk groeien; decomposities en eigenwaarden kunnen daardoor aan nauwkeurigheid verliezen. Zeer extreme gevallen kunnen numerieke limieten overschrijden en een fout geven.
De volledige regels staan in de referentie voor geavanceerde wiskunde.
Alles combineren
Drie marktbonnen vermelden de aantallen appels, bananen en sinaasappels en het totaalbedrag, maar niet de stukprijzen:
# Each row: apples, bananas, orangesbaskets = [[2, 3, 1], [1, 2, 3], [4, 1, 2]]paid = [2.15, 2.70, 3.05]det(baskets) geeft 25prices = solve_system(baskets, paid) geeft [0.4, 0.25, 0.6]# Check the prices against every receiptbaskets * transpose([prices]) geeft [[2.15], [2.7], [3.05]]# What would 5 apples, 2 bananas and 4 oranges cost?dot([5, 2, 4], prices) geeft 4.9De niet-nulle determinant bevestigt dat de bonnen één unieke prijzenset bepalen: appels 40p, bananen 25p en sinaasappels 60p. Vermenigvuldigen van de mandjes met de prijzen als kolom geeft de totalen terug; dot berekent £4,90 voor een nieuw mandje.