English  Español  Português  Français  Italiano  Deutsch  Nederlands  Svenska  Dansk  Suomi  Norsk  Русский  Polski  Română  Български  Hrvatski  Česky  中国  中國  日本語  한국어  Ελληνική  हिन्दी  العربية 
Lineární algebra
Colin Fahey

1. Software

LinearAlgebra.zip
Lineární algebry zdrojový kód (C#)
19910 bytů
MD5: 11d8c8035cac30ba543e5e0b72ee9767

2. Úvod

Tento článek popisuje, vektory a maticemi v (d)-rozměrném prostoru.

3. (d)-rozměrném prostoru: atributy

3.1 Array

"pole:" Soubor proměnných taková, že každá proměnná má jedinečný název, a taková, že jména mohou být přiřazeny objednávky.
Celočíselné hodnoty mohou být použity jako názvy proměnných v poli.
Například v případě, že pole obsahuje (d) proměnných, pak je celé hodnoty { 0, 1, 2, ..., (d-1) } mohou být přiřazeny názvy proměnných v poli.

3.2 (d)-dimenzionální vektorové

"(d)-dimenzionální vektor:" pole na (d) proměnných.
"vektorové složky:" Proměnná ve vektoru.

3.3 (d)-dimenzionální vektorový prostor

"jedno-rozměrném prostoru:" Kompletní soubor hodnot, které mohou být uloženy do jedné proměnné.
"(d)-rozměrném prostoru:" Kompletní sada kombinace hodnot, které mohou být uloženy na několik (d) proměnných.
Formální definice "vektorového prostoru:"
Nechte (T) být základní typy (příklady: reálné číslo, celé číslo, komplexní číslo, racionální číslo, atd.).
Každá proměnná ze základního typu se označuje jako "skalární."
A "(T)-typ (d)-dimenzionální vektorový prostor" je sada (S) na (d)-rozměrné vektory, které mají dvě operace, vektorové navíc (+), a skalární násobení (*), splňující níže uvedené podmínky:
(1) Je-li (v) a (w) se dvěma vektory v (S), pak (v + w) je také vektor v (S);
(2) Je-li (u), (v), a (w) jsou všechny tři vektory v (S), pak (u + v) + w = u + (v + w);
[přídatné látky komutativita]
(3) Je-li (v) a (w) se dvěma vektory v (S), pak (v + w) = (w + v);
[přídatné látky asociativnost]
(4) Je "nula vektoru," (0), v (S), takové, že pro každého vektoru (v) v (S), (v + (0)) = v;
[přídatné látky identitu]
(5) Pokud je (c) jakékoli skalární typu (T), a (v) je jakýkoli vektor v (S), potom produkt (c * v) je vektor v (S);
(6) Pokud (a), (b), a (c) jsou všechny skaláry typu (T), a (v) a (w) jsou všechny vektory v (S), pak (a + b) * v = a*v + b*v, a c*(v + w) = c*v + c*w;
[multiplikativní distributivnost]
(7) Je-li (a) a (b) jsou všechny skaláry typu (T), a (v) je jakýkoli vektor v (S), pak (a*b)*v = a*(b*v);
(8) Je-li "1" je skalární typu (T) taková, že (1*1)=1, a (v) je jakýkoli vektor v (S), pak (1*v) = v;
(9) Pro každý vektor (v) v (S), vektoru (-1)*v = -v splňuje v + (-v) = (0);
[Opačné]

3.4 (d)-rozměrné vektorové kód

Následující kód ukazuje, jak (d)-dimenzionální vektor, s 64-bitovou plovoucí-bod, komponenty, může být provedena.
Pole je dostatečné k tomu, aby představují vektor.
Následující kód má pole obsažené ve třídě, pouze pro pohodlí.
Tento kód není určen jako účinná.
Strukturou (příklad: "struct", jejichž hodnota je typu) zastupující vektory z pevné linky na rozměry (příklady: 3 nebo 4), které by mohly být mnohem účinnější než obecný (d)-dimenzionální vektor třídy naleznete zde.
Ačkoliv níže uvedený kód definuje vektor s plovoucí-bod složek se v tomto dokumentu rovněž využívá vektory se celé složky.
Následující kód může být snadno upraven k provádění vektory se celé složky.
using System;
using System.Collections.Generic;
using System.Text;

// Multidimensional vector with 64-bit floating-point components:

public class VectorF64
{
    private double[] components;




    public int Dimensions()
    {
        if (null == this.components)
        {
            return (0);
        }

        return (this.components.Length);
    }




    public VectorF64()
    {
        this.components = null;
    }




    public VectorF64params double[] paramValues )
    {
        this.components = null;

        if (null == paramValues)
        {
            return;
        }

        int dimensions = paramValues.Length;

        this.components = new double[dimensions];

        for (int i = 0; i < dimensions; i++)
        {
            this.components[i] = paramValues[i];
        }
    }




    public VectorF64VectorF64 other )
    {
        this.components = null;

        if (null == other)
        {
            return;
        }

        if (null == other.components)
        {
            return;
        }

        int dimensions = other.Dimensions();

        this.components = new double[dimensions];

        for (int i = 0; i < dimensions; i++)
        {
            this.components[i] = other.components[i];
        }
    }




    public double this[int index]
    {
        get
        {
            if (null == this.components)
            {
                return (0.0);
            }

            if
            (
                   (index >= 0)
                && (index < this.components.Length)
            )
            {
                return (this.components[index]);
            }

            return (0.0);
        }

        set
        {
            if (null == this.components)
            {
                return;
            }

            if
            (
                   (index >= 0)
                && (index < this.components.Length)
            )
            {
                this.components[index] = value;
            }
        }
    }




    public void Write( int precision )
    {
        if (null == this.components)
        {
            Log.Write( String.Empty + '(' + ' ' + ')' );
            return;
        }

        int dimensions = this.Dimensions();
        if (0 == dimensions)
        {
            Log.Write( String.Empty + '(' + ' ' + ')' );
            return;
        }

        // Determine the largest component width in characters
        // so that we can make all components an equal width.
        int largestComponentWidth = 1;
        for (int i = 0; i < dimensions; i++)
        {
            // { index [,minwidth] [:typeCode[precision]] }
            //      (minwidth<0) means left-justify
            String text = String.Format( String.Empty + '{' + '0' + ':'
                + 'g' + precision + '}', this[i] );
            if (text.Length > largestComponentWidth)
            {
                largestComponentWidth = text.Length;
            }
        }

        Log.Write( '(' );
        for (int i = 0; i < dimensions; i++)
        {
            Log.Write( ' ' );
            String text =
                String.Format( String.Empty + '{' + '0' + ','
                + largestComponentWidth + ':' + 'g' + precision + '}',
                this[i] );
            Log.Write( text );
            if ((i + 1) < dimensions)
            {
                Log.Write( ',' );
            }
            else
            {
                Log.Write( ' ' );
            }
        }
        Log.Write( ')' );
    }




    public void WriteLine( int precision )
    {
        this.Write( precision );
        Log.WriteLine();
    }




    public void WriteLine()
    {
        const int defaultPrecision = 8;
        this.Write( defaultPrecision );
        Log.WriteLine();
    }




    // . . .




    public static void Test()
    {
        // A 3-dimensional vector with 64-bit floating-point components:
        VectorF64 v3 = new VectorF640.01.02.0 );
        v3.WriteLine(); // ( 0, 1, 2 )

        // A 4-dimensional vector with 64-bit floating-point components:
        VectorF64 v4 = new VectorF640.01.02.03.0 );
        v4.WriteLine(); // ( 0, 1, 2, 3 )

        // . . .
    }
}
"(d)-dimenzionálním nulový vektor:" A vektor se všemi (d) komponenty se rovná nule.
public class VectorF64
{
    // . . .




    public static VectorF64 Zero( int dimensions )
    {
        VectorF64 zero = new VectorF64();

        zero.components = new double[dimensions];

        for (int i = 0; i < dimensions; i++)
        {
            zero[i] = 0.0;
        }

        return (zero);
    }




    // . . .




    public static void Test()
    {
        // . . .


        // An 8-dimensional vector with all 8 64-bit floating-point
        // components set to zero:
        VectorF64 z = VectorF64.Zero( 8 );
        z.WriteLine(); // ( 0, 0, 0, 0, 0, 0, 0, 0 )


        // . . .
    }
}

3.5 (d)-rozměrném prostoru: body

"(d)-rozměrném prostoru bod:" V současnosti je přijímána řada (d) proměnné s konkrétní hodnoty "(koordinovat hodnoty)."
"(d)-rozměrném prostoru původu:" pole na (d) všechny hodnoty proměnné se rovnají nule.

3.6 (d)-rozměrné vektory: non-relativní a relativní

A (d)-dimenzionální vektor, který je "ne-relativní" je (d)-dimenzionální vektor, který přímo reprezentuje stav nebo konfigurace.
A (d)-dimenzionální vektor, který je "relativní" je (d)-dimenzionální vektor, které představuje změny v souboru složek.
Relativní vektor může představovat rozdíl mezi dvěma ne-relativní vektory.
Vzhledem k relativní vektor, se stanoví mimo-relativní postavení a konfigurace pomocí tohoto relativního vektoru vyžaduje kombinování, že relativní vektor s non-relativní vektor.
Non-relativní vektory a relativní vektory jsou vektory.
Ať už se jedná o konkrétní vektor, není-relativní nebo relativní musí být upřesněno, kdy vektor je definován.
Pokud se (d)-dimenzionální vektor je interpretována tak, aby ne-relativní, pak je (d)-dimenzionální vektor může představovat místo v (d)-rozměrném prostoru.

3.7 (d)-rozměrné vektorové sčítání, odečítání, a škálování

Vektorové sčítání, odečítání, a škálování:
public class VectorF64
{
    // . . .




    public static VectorF64 operator +( VectorF64 a, VectorF64 b )
    {
        if ((null == a) ¦¦ (null == b))
        {
            return (new VectorF64()); // Vector not specified.
        }

        if ((null == a.components) ¦¦ (null == b.components))
        {
            return (new VectorF64()); // Vector is empty.
        }

        if (a.Dimensions() != b.Dimensions())
        {
            return (new VectorF64()); // Vectors not the same size.
        }

        int dimensions = a.Dimensions();

        VectorF64 result = VectorF64.Zero( dimensions );

        for (int i = 0; i < dimensions; i++)
        {
            result[i] = a[i] + b[i];
        }

        return (result);
    }




    public static VectorF64 operator -( VectorF64 a, VectorF64 b )
    {
        if ((null == a) ¦¦ (null == b))
        {
            return (new VectorF64()); // Vector not specified.
        }

        if ((null == a.components) ¦¦ (null == b.components))
        {
            return (new VectorF64()); // Vector is empty.
        }

        if (a.Dimensions() != b.Dimensions())
        {
            return (new VectorF64()); // Vectors not the same size.
        }

        int dimensions = a.Dimensions();

        VectorF64 result = VectorF64.Zero( dimensions );

        for (int i = 0; i < dimensions; i++)
        {
            result[i] = a[i] - b[i];
        }

        return (result);
    }




    public static VectorF64 operator -( VectorF64 a )
    {
        if (null == a)
        {
            return (new VectorF64()); // Vector not specified.
        }

        if (null == a.components)
        {
            return (new VectorF64()); // Vector is empty.
        }

        int dimensions = a.Dimensions();

        VectorF64 result = VectorF64.Zero( dimensions );

        for (int i = 0; i < dimensions; i++)
        {
            result[i] = (-( a[i] ));
        }

        return (result);
    }




    public static VectorF64 operator *( double scale, VectorF64 a )
    {
        if (null == a)
        {
            return (new VectorF64()); // Vector not specified.
        }

        if (null == a.components)
        {
            return (new VectorF64()); // Vector is empty.
        }

        int dimensions = a.Dimensions();

        VectorF64 result = VectorF64.Zero( dimensions );

        for (int i = 0; i < dimensions; i++)
        {
            result[i] = scale * a[i];
        }

        return (result);
    }




    public static VectorF64 operator *( VectorF64 a, double scale )
    {
        if (null == a)
        {
            return (new VectorF64()); // Vector not specified.
        }

        if (null == a.components)
        {
            return (new VectorF64()); // Vector is empty.
        }

        int dimensions = a.Dimensions();

        VectorF64 result = VectorF64.Zero( dimensions );

        for (int i = 0; i < dimensions; i++)
        {
            result[i] = scale * a[i];
        }

        return (result);
    }




    // . . .




    public static void Test()
    {
        // . . .


        // Examples of vector addition, subtraction, and scaling:

        VectorF64 a = new VectorF640.01.02.03.0 );
        a.WriteLine(); // ( 0, 1, 2, 3 )
        VectorF64 b = new VectorF643.02.01.00.0 );
        b.WriteLine(); // ( 3, 2, 1, 0 )
        VectorF64 c = new VectorF64();
        c.WriteLine(); // ( )

        c = a + b;
        c.WriteLine(); // ( 3, 3, 3, 3 )

        c = a - b;
        c.WriteLine(); // ( -3, -1,  1,  3 )

        c = -b;
        c.WriteLine(); // ( -3, -2, -1,  0 )

        c = 3.0 * a;
        c.WriteLine(); // ( 0, 3, 6, 9 )


        // . . .
    }
}

3.8 (d)-dimenzionálním základě vektorů

Formální definice "na" bázi vektorového prostoru:
Nechte (T) být základní typy (příklady: reálné číslo, celé číslo, komplexní číslo, racionální číslo, atd.).
Každá proměnná ze základního typu se označuje jako "skalární."
Nechte (V) být "(T)-typ (d)-dimenzionální vektorový prostor."
Pokud non-nulové vektory { u1, u2, ..., ud } v (V) jsou takové, že každý vektor (v) v (V) lze zapsat jako "lineární kombinace" těchto vektorů, v = c1*u1 + c2*u2 + ...  + cd*ud, kde { c1, c2, ..., cd } jsou skaláry typu (T), pak (V) je "rozložené" vektory { u1, u2, ..., ud }.
Každá sada non-nulové vektory { u1, u2, ..., ud } "span," že vektorový prostor (V) je pojmenován "na" bázi (V).
Jeden jednoduchý "základ" pro (d)-dimenzionální vektorový prostor je množina (d) odlišné (d)-rozměrné vektory, každý s jedním složky ve výši jedné a všechny ostatní součásti se rovná nule.
Takový základ vektory jsou "ortonormální," což znamená, že jsou-vzájemně kolmé "(ortogonální)" a že každý vektor má délku jednotky.
Každý takový vektor je vektor paralelní jednotky do jedné z (d) koordinuje os.
Vyjádření libovolného vektoru jako "lineární kombinace" těchto vektorů je základ přímo; každou část libovolného vektoru se násobí odpovídající základ vektor, a tyto produkty se sčítají za účelem vytvoření libovolného vektoru.
Následující kód ukazuje, jak se vektor lze vyjádřit jako "lineární kombinaci" na základě vektorů.
Následující kód libovolně definuje ortonormální soubor základě vektory.
public class VectorF64
{
    // . . .




    public static VectorF64 BasisVector( int dimensions, int componentIndex )
    {
        if (dimensions < 0)
        {
            // Invalid number of dimensions specified.
            return (new VectorF64());
        }

        VectorF64 basisVector = VectorF64.Zero( dimensions );

        if ((componentIndex >= 0) && (componentIndex < dimensions))
        {
            basisVector[ componentIndex ] = 1.0;
        }

        return (basisVector);
    }




    // . . .




    public static void Test()
    {

        // . . .


        // The 4 basis vectors of 4-dimensional space,
        // each with 4 64-bit floating-point components:

        VectorF64 b0 = VectorF64.BasisVector( 40 );
        b0.WriteLine(); // ( 1, 0, 0, 0 )

        VectorF64 b1 = VectorF64.BasisVector( 41 );
        b1.WriteLine(); // ( 0, 1, 0, 0 )

        VectorF64 b2 = VectorF64.BasisVector( 42 );
        b2.WriteLine(); // ( 0, 0, 1, 0 )

        VectorF64 b3 = VectorF64.BasisVector( 43 );
        b3.WriteLine(); // ( 0, 0, 0, 1 )


        // . . .
    }
}
Jakýkoliv vektor v (d)-rozměrném prostoru lze vyjádřit jako součet těchto produktů na základě čísel a vektorů:
public class VectorF64
{
    // . . .




    public static void Test()
    {

        // . . .


        // The following two vectors are equivalent:

        // A 4-dimensional vector with 64-bit floating-point components:
        VectorF64 va = new VectorF640.11.12.23.3 );
        va.WriteLine(); // ( 0.1, 1.1, 2.2, 3.3 )

        // A 4-dimensional vector formed by scaling the 4 independent
        // basis vectors for 4-dimensional space:
        VectorF64 vb =
              0.1 * VectorF64.BasisVector( 40 )
            + 1.1 * VectorF64.BasisVector( 41 )
            + 2.2 * VectorF64.BasisVector( 42 )
            + 3.3 * VectorF64.BasisVector( 43 );
        vb.WriteLine(); // ( 0.1, 1.1, 2.2, 3.3 )


        // . . .
    }
}

3.9 (d)-rozměrném prostoru: vzdálenost mezi body

Nechte (P) být (d)-dimenzionální vektor, které představuje místo v (d)-rozměrném prostoru.
Nechte (Q) být (d)-dimenzionální vektor, které představuje místo v (d)-rozměrném prostoru.
Nechte (R) být (d)-dimenzionální vektor, který představuje změnu v (d) souřadnice se dostat z bodu (P) bodu (Q); R = (Q - P).
V jednom-rozměrném prostoru, P = ( p0 ), Q = ( q0 ), a R = (Q - P) = ( q0 - p0 ).
Vzdálenost mezi oběma body je: Abs( q0 - p0 ).
Ve dvou-rozměrném prostoru, P = ( p0, p1 ), Q = ( q0, q1 ), a R = (Q - P) = ( q0-p0, q1-p1 ).
Význam dvou kolmých posuvu jako kolmé břehy právo-trojúhelník, vzdálenost mezi body odpovídá délce části přepona tohoto trojúhelníku.
Na Pythagorean vzorec, (a*a) + (b*b) = (c*c), kde (a) a (b) jsou délky kolmicí stranách právo-trojúhelník, a (c) je doba trvání přepona (pořádání straně), může být použita pro určení vzdálenosti mezi dvěma body: Sqrt( Sq(q0-p0) + Sq(q1-p1) ).
Ve tří-rozměrném prostoru, P = ( p0, p1, p2 ), Q = ( q0, q1, q2 ), a R = (Q - P) = ( q0-p0, q1-p1, q2-p2 ).
Význam vysídlení ( q0-p0, q1-p1, 0 ) jako kolmé břehy právo-trojúhelník, a pomocí Pythagorean vzorec, dává vzdálenost mezi bodem (P) a místo ( q0, q1, p2 ): d01 = Sqrt( Sq(q0-p0) + Sq(q1-p1) ).
Posunutí ( q0-p0, q1-p1, 0 ) je kolmo k posuvu ( 0, 0, q2-p2 ), a jiné právo-trojúhelník může být formována, a Pythagorean vzorec lze použít znovu.
Proto je vzdálenost od bodu (P) bodu (Q) je dána: Sqrt( Sq(d01) + Sq(q2-p2) ) = Sqrt( (Sq(q0-p0) + Sq(q1-p1)) + Sq(q2-p2) ) = Sqrt( Sq(q0-p0) + Sq(q1-p1) + Sq(q2-p2) ).
Způsob prodlužuje vzdálenost vzorec ze dvou-rozměrném prostoru až tří-rozměrném prostoru lze aplikovat opakovaně, aby nakonec určit vzdálenost vzorec pro (d)-rozměrném prostoru: Sqrt( (Sq(q0-p0) + Sq(q1-p1)) + Sq(q2-p2) + ...  + Sq(qd-pd) ).
Následující kód definuje funkci s názvem "Délka" který počítá délku a (d)-dimenzionální vektor.
Pokud je vektor reprezentuje posunutí mezi dvěma body na (d)-rozměrném prostoru, délky vektoru představuje vzdálenost mezi těmito dvěma body.
public class VectorF64
{
    // . . .




    public double Length()
    {
        if (null == this.components)
        {
            return (0.0); // Vector empty.
        }

        int dimensions = this.Dimensions();

        double sumOfSquares = 0.0;
        for (int i = 0; i < dimensions; i++)
        {
            sumOfSquares += (this[i] * this[i]);
        }

        double length = Math.Sqrt( sumOfSquares );

        return (length);
    }




    public static double Length( VectorF64 a )
    {
        if (null == a)
        {
            return (0.0); // Vector not specified.
        }

        if (null == a.components)
        {
            return (0.0); // Vector is empty.
        }

        return (a.Length());
    }




    // . . .




    public static void Test()
    {
        // . . .


        // Example of vector length:

        // A 6-dimensional vector representing a point (p):
        VectorF64 p = new VectorF640.01.02.03.04.05.0 );
        p.WriteLine(); // ( 0, 1, 2, 3, 4, 5 )

        // A 6-dimensional vector representing a point (q):
        VectorF64 q = new VectorF64-5.04.0-3.02.0-1.00.0 );
        q.WriteLine(); // ( -5,  4, -3,  2, -1,  0 )

        // A 6-dimensional vector representing the displacement
        // from point (p) to point (q):
        VectorF64 r = q - p;
        r.WriteLine(); // ( -5,  3, -5, -1, -5, -5 )

        // The distance between point (p) and point (q)
        // in 6-dimensional space:
        double distance = r.Length();
        Log.WriteLine( distance ); // 10.4880884817015


        // . . .
    }
}

3.10 (d)-rozměrné vektory: skalární součin

"Tečka produktu" převádí dva (d)-rozměrné vektory na řadu.
Následující kód spočítáme tečkou produktu dvou vektorů:
public class VectorF64
{
    // . . .





    public static double Dot( VectorF64 a, VectorF64 b )
    {
        if ((null == a) ¦¦ (null == b))
        {
            return (0.0); // Vector not specified.
        }

        if ((null == a.components) ¦¦ (null == b.components))
        {
            return (0.0); // Vector is empty.
        }

        if (a.Dimensions() != b.Dimensions())
        {
            return (0.0); // Vectors not the same size.
        }

        int dimensions = a.Dimensions();

        double dotProduct = 0.0;
        for (int i = 0; i < dimensions; i++)
        {
            dotProduct += (a[i] * b[i]);
        }

        return (dotProduct);
    }




    // . . .
}
Pro každého vektoru, (A), Length(A) = Sqrt(Dot(A,A)).

3.11 (d)-rozměrné vektory: definice "paralelní"

Vektory (A) a (B) jsou "rovnoběžné," pokud všechny tyto jsou pravdivé:
(1) A.Length() > 0;
(2) B.Length() > 0;
(3) Abs(Dot(A,B)) = A.Length()*B.Length().
Následující kód určuje, je-li pár vektory jsou rovnoběžné (případně anti-sladěna).
Plovoucí-bod čísla mohou hromadit chyby v frakční část vzhledem k omezené přesnosti, a proto, počítačový kód by měl obsahovat non-nulové tolerance při porovnání plovoucí-bod čísel.
Tento kodex obsahuje například hodnoty tolerance, ale například toleranci hodnot nemusí být vhodné pro některé úkoly.
public class VectorF64
{
    // . . .




    public static bool Parallel( VectorF64 a, VectorF64 b )
    {
        // Smallest normalized float : 1.1754943e-38
        // Smallest normalized double: 2.2250738585072020e-308
        double nonZeroThreshold = 1.0e-38// conservative for double
        // double: (52+1)-bit mantissa; log10(2^53)=15.95 decimal digits
        double fractionalDifferenceThreshold = 1.0e-14// conservative

        if ((null == a) ¦¦ (null == b))
        {
            return (false); // Vector is not specified.
        }

        if ((null == a.components) ¦¦ (null == b.components))
        {
            return (false); // Vector is empty.
        }

        if (a.Dimensions() != b.Dimensions())
        {
            return (false); // Vectors not the same size.
        }

        double lengthA = a.Length();
        if (lengthA <= nonZeroThreshold)
        {
            return (false);
        }

        double lengthB = b.Length();
        if (lengthB <= nonZeroThreshold)
        {
            return (false);
        }

        double oneImpliesParallel =
            Math.Abs( VectorF64.Dot( a, b ) ) / (lengthA * lengthB);

        double absoluteDifferenceFromOne =
            Math.Abs( oneImpliesParallel - 1.0 );

        if (absoluteDifferenceFromOne <= fractionalDifferenceThreshold)
        {
            return (true);
        }

        return (false);
    }




    // . . .




    public static void Test()
    {
        // . . .


        // Example of testing for parallel vectors:

        // A 6-dimensional vector:
        VectorF64 vf = new VectorF640.01.02.03.04.05.0 );
        vf.WriteLine(); // ( 0, 1, 2, 3, 4, 5 )

        // A 6-dimensional vector:
        VectorF64 vg = new VectorF640.0-2.0-4.0-6.0-8.0-10.0 );
        vg.WriteLine(); // (   0,  -2,  -4,  -6,  -8, -10 )

        // Determine if the specified vectors are parallel
        // (or "anti-aligned"):
        bool parallel = VectorF64.Parallel( vf, vg );
        Log.WriteLine( parallel ); // True

        // Add a non-negligible displacement to a component of a vector:
        vf[0] += 1.0e-5;
        vf.WriteLine(); // ( 1E-05,     1,     2,     3,     4,     5 )

        // Determine if the specified vectors are parallel
        // (or "anti-aligned"):
        parallel = VectorF64.Parallel( vf, vg );
        Log.WriteLine( parallel ); // False


        // . . .
    }
}

3.12 (d)-rozměrné vektory: definice "kolmá"

Vektory (A) a (B) jsou "kolmé," jestliže všechny následující jsou pravdivé:
(1) A.Length() > 0;
(2) B.Length() > 0;
(3) Abs(Dot(A,B)) = 0.
Následující kód určuje, je-li pár vektory jsou kolmé.  Plovoucí-bod čísla mohou hromadit chyby v frakční část vzhledem k omezené přesnosti, a proto, počítačový kód by měl obsahovat non-nulové tolerance při porovnání plovoucí-bod čísel.
Tento kodex obsahuje například hodnoty tolerance, ale například toleranci hodnot nemusí být vhodné pro některé úkoly.
public class VectorF64
{
    // . . .




    public static bool Perpendicular( VectorF64 a, VectorF64 b )
    {
        // Smallest normalized float : 1.1754943e-38
        // Smallest normalized double: 2.2250738585072020e-308
        double nonZeroThreshold = 1.0e-38// conservative for double
        // double: (52+1)-bit mantissa; log10(2^53)=15.95 decimal digits
        double fractionalDifferenceThreshold = 1.0e-14// conservative

        if ((null == a) ¦¦ (null == b))
        {
            return (false); // Vector is not specified.
        }

        if ((null == a.components) ¦¦ (null == b.components))
        {
            return (false); // Vector is empty.
        }

        if (a.Dimensions() != b.Dimensions())
        {
            return (false); // Vectors not the same size.
        }

        double lengthA = a.Length();
        if (lengthA <= nonZeroThreshold)
        {
            return (false);
        }

        double lengthB = b.Length();
        if (lengthB <= nonZeroThreshold)
        {
            return (false);
        }

        double zeroImpliesPerpendicular =
            Math.Abs( VectorF64.Dot( a, b ) ) / (lengthA * lengthB);

        double absoluteDifferenceFromZero =
            Math.Abs( zeroImpliesPerpendicular );

        if (absoluteDifferenceFromZero <= fractionalDifferenceThreshold)
        {
            return (true);
        }

        return (false);
    }




    // . . .




    public static void Test()
    {
        // . . .


        // Example of testing for perpendicular vectors:

        // A 6-dimensional vector:
        VectorF64 vf2 = new VectorF640.01.02.00.04.05.0 );
        vf2.WriteLine(); // ( 0, 1, 2, 0, 4, 5 )

        // A 6-dimensional vector:
        VectorF64 vg2 = new VectorF6410.00.00.0-5.00.00.0 );
        vg2.WriteLine(); // ( 10,  0,  0, -5,  0,  0 )

        // Determine if the specified vectors are perpendicular
        bool perpendicular = VectorF64.Perpendicular( vf2, vg2 );
        Log.WriteLine( perpendicular ); // True

        // Add a non-negligible displacement to a component of a vector:
        vf2[0] += 1.0e-13;
        vf2.WriteLine(); // ( 1E-13,    1,    2,    0,    4,    5 )

        // Determine if the specified vectors are perpendicular
        perpendicular = VectorF64.Perpendicular( vf2, vg2 );
        Log.WriteLine( perpendicular ); // False


        // . . .
    }
}

3.13 Matice

"matice:" Soubor proměnných taková, že každá proměnná má jedinečnou kombinaci "po" sobě jména, příjmení a názvu "sloupce."
"vstup:" Proměnná v matrice.
Celočíselné hodnoty mohou být použity jako "řádek" jména a názvy "sloupců" pro proměnné v matice.
Například, je-li matice má (totalRows) řádků a sloupců (totalColumns), pak je celé hodnoty { 0, 1, ..., (totalRows-1) } mohou být názvy přiřazeny řádky, a integer hodnoty { 0, 1, ..., (totalColumns-1) } mohou být přiřazeny názvy sloupců.
Což znamená, že proměnné v matici, může být stanoveno, že se stanoví dvojice celá čísla, ( row, column ), což naznačuje, kombinace řádku a sloupci indexy odpovídající konkrétní proměnnou.
Velikost matice je uvedena jako "(totalRows) * (totalColumns)" (nebo "(totalRows) o (totalColumns))."
Toto pořadí rozměry jsou stejné jako pořadí na rozměry použitých upřesnit zápisy v matrice "(( row, column ))."
[Tato úmluva je poněkud nešťastné, protože pro mnohé dva-dimenzionálním použití (příklady: obrázky, grafy, atd.), obvyklé konvence je specifikovat rozměry jako "width * height" a souřadnice jako "( horizontal, vertical )" (nebo "( x, y ))."
To je přesný opak toho řádově rozměry a souřadnice se používá k označení matice a jejich zápisy.  ]
Matice s (totalRows) rovná (totalColumns) se jmenuje "náměstí," jinak matrice se jmenuje "obdélníkové."
Matice může být považováno za obsahující soubor "řádek vektory," kde se proměnné v každém řádku jsou interpretovány jako něco, co patří k vektoru.
Matice se lze také obsahuje soubor "sloupce vektory," kde se proměnné v každém sloupci jsou interpretována jako něco, co patří k vektoru.
Matice může reprezentovat celou řadu matematických vztahů.
Význam matice a operace, které by mohly být vhodné pro zpracování záznamů z matice, závisí na kontextu.
Nicméně, existují základní pravidla, na matrice aritmetika, které jsou významné pro mnoho kontextů, a tyto základní pravidla budou stanoveny v následující části.
Pole a (totalColumns) hodnoty jsou dostatečné k tomu, aby představují matice.
Poli může mít (totalRows * totalColumns) proměnných, a vstup na ( row, column ) může odpovídat na pole proměnné v indexu ((totalColumns * row) + column).
Následující kód definuje matici, s 64-bitovou plovoucí-bod zápisy.
Pole a (totalColumns) hodnoty jsou dostatečné k tomu, aby představují matice.
Následující kód je pole a (totalColumns) hodnoty obsažené ve třídě, pouze pro pohodlí.
Následující kód je nelze považovat za efektivní.
Strukturou (příklad: "struct", jejichž hodnota je typu) reprezentující matice na konkrétní pevné rozměry (příklady: 2*2, 3*3, nebo 4*4), které by mohly být mnohem účinnější než obecný (totalRows * totalColumns) třídy naleznete zde.