πŸ“– ДокумСнтация Qumir

← Π’Π΅Ρ€Π½ΡƒΡ‚ΡŒΡΡ Π² Playground

← ВсС ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹

Π£ΠΌΠ½ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠ°Ρ‚Ρ€ΠΈΡ†

Π£ΠΌΠ½ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π΄Π²ΡƒΡ… ΠΌΠ°Ρ‚Ρ€ΠΈΡ† -- Ρ„ΡƒΠ½Π΄Π°ΠΌΠ΅Π½Ρ‚Π°Π»ΡŒΠ½Π°Ρ опСрация Π»ΠΈΠ½Π΅ΠΉΠ½ΠΎΠΉ Π°Π»Π³Π΅Π±Ρ€Ρ‹, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠ°Ρ Π² ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π½ΠΎΠΉ Π³Ρ€Π°Ρ„ΠΈΠΊΠ΅, машинном ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΠΈ, Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΈ систСм ΡƒΡ€Π°Π²Π½Π΅Π½ΠΈΠΉ ΠΈ мноТСствС Π΄Ρ€ΡƒΠ³ΠΈΡ… Π·Π°Π΄Π°Ρ‡. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° вычисляСт ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½ΠΈΠ΅ $C = A \cdot B$ для Π½ΠΈΠΆΠ½Π΅Ρ‚Ρ€Π΅ΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΎΠΉ ΠΈ Π²Π΅Ρ€Ρ…Π½Π΅Ρ‚Ρ€Π΅ΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΎΠΉ ΠΌΠ°Ρ‚Ρ€ΠΈΡ† ΠΈ провСряСт Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΏΠΎ аналитичСской Ρ„ΠΎΡ€ΠΌΡƒΠ»Π΅.

Π—Π°Π΄Π°Ρ‡Π°

Π’Ρ‹Ρ‡ΠΈΡΠ»ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½ΠΈΠ΅ Π΄Π²ΡƒΡ… ΠΌΠ°Ρ‚Ρ€ΠΈΡ† $A$ ΠΈ $B$ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° $n \times n$:

$C_{i,j} = \sum_{k=0}^{n-1} A_{i,k} \cdot B_{k,j}, \quad i,j = 0, \ldots, n-1$

Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ:

ΠžΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚: $C_{i,j} = \min(i, j) + 1$ -- симмСтричная ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π°.

ИдСя Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ°

  1. Π—Π°ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Ρƒ $A$ (Π½ΠΈΠΆΠ½ΠΈΠΉ Ρ‚Ρ€Π΅ΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ -- Π΅Π΄ΠΈΠ½ΠΈΡ†Ρ‹) ΠΈ ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Ρƒ $B$ (Π²Π΅Ρ€Ρ…Π½ΠΈΠΉ Ρ‚Ρ€Π΅ΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ -- Π΅Π΄ΠΈΠ½ΠΈΡ†Ρ‹).
  2. Π’Ρ‹Ρ‡ΠΈΡΠ»ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½ΠΈΠ΅ $C = A \cdot B$ Ρ‚Ρ€ΠΎΠΉΠ½Ρ‹ΠΌ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΌ Ρ†ΠΈΠΊΠ»ΠΎΠΌ ΠΏΠΎ $i$, $j$, $k$.
  3. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚: для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ элСмСнта Π²Ρ‹Ρ‡ΠΈΡΠ»ΠΈΡ‚ΡŒ ΠΎΡˆΠΈΠ±ΠΊΡƒ $e_{i,j} = C_{i,j} - C_{i,j}^{\text{exact}}$ ΠΈ вывСсти Π½ΠΎΡ€ΠΌΡ‹ $|e|2$ ΠΈ $|e|\infty$.

Π Π°Π·Π±ΠΎΡ€

ОбъявлСниС Π΄Π°Π½Π½Ρ‹Ρ…

Π—Π°Π΄Π°Ρ‘ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ $n = 128$ ΠΈ объявляСм Ρ‚Ρ€ΠΈ Π΄Π²ΡƒΠΌΠ΅Ρ€Π½Ρ‹Ρ… массива для ΠΌΠ°Ρ‚Ρ€ΠΈΡ† $A$, $B$ ΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° $C$:

  Ρ†Π΅Π» n,i,j,k
  n := 128
  Π²Π΅Ρ‰ Ρ‚Π°Π± A[0:n-1,0:n-1]
  Π²Π΅Ρ‰ Ρ‚Π°Π± B[0:n-1,0:n-1]
  Π²Π΅Ρ‰ Ρ‚Π°Π± C[0:n-1,0:n-1]
  Π²Π΅Ρ‰ sum, err, absv, res_l2_sq, res_l2, res_inf

Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ ΠΌΠ°Ρ‚Ρ€ΠΈΡ†

ЗаполняСм $A$ ΠΈ $B$ Π² ΠΎΠ΄Π½ΠΎΠΌ Π΄Π²ΠΎΠΉΠ½ΠΎΠΌ Ρ†ΠΈΠΊΠ»Π΅. $A_{i,j} = 1$ ΠΏΡ€ΠΈ $j \le i$ (Π½ΠΈΠΆΠ½ΠΈΠΉ Ρ‚Ρ€Π΅ΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ), $B_{i,j} = 1$ ΠΏΡ€ΠΈ $j \ge i$ (Π²Π΅Ρ€Ρ…Π½ΠΈΠΉ Ρ‚Ρ€Π΅ΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ):

  | Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ A (Π½ΠΈΠΆΠ½ΠΈΠΉ Ρ‚Ρ€Π΅ΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ) ΠΈ B (Π²Π΅Ρ€Ρ…Π½ΠΈΠΉ Ρ‚Ρ€Π΅ΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ)
  Π½Ρ† для i ΠΎΡ‚ 0 Π΄ΠΎ n-1
    Π½Ρ† для j ΠΎΡ‚ 0 Π΄ΠΎ n-1
      Ссли j <= i Ρ‚ΠΎ A[i,j] := 1.0 ΠΈΠ½Π°Ρ‡Π΅ A[i,j] := 0.0 всС
      Ссли j >= i Ρ‚ΠΎ B[i,j] := 1.0 ΠΈΠ½Π°Ρ‡Π΅ B[i,j] := 0.0 всС
    ΠΊΡ†
  ΠΊΡ†

Π’Ρ€ΠΎΠΉΠ½ΠΎΠΉ Ρ†ΠΈΠΊΠ» умноТСния

ΠšΠ»Π°ΡΡΠΈΡ‡Π΅ΡΠΊΠΈΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ: для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΏΠ°Ρ€Ρ‹ $(i, j)$ вычисляСм скалярноС ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½ΠΈΠ΅ $i$-ΠΉ строки $A$ Π½Π° $j$-ΠΉ столбСц $B$:

  | ВычисляСм C = A * B
  Π½Ρ† для i ΠΎΡ‚ 0 Π΄ΠΎ n-1
    Π½Ρ† для j ΠΎΡ‚ 0 Π΄ΠΎ n-1
      sum := 0.0
      Π½Ρ† для k ΠΎΡ‚ 0 Π΄ΠΎ n-1
        sum := sum + A[i,k] * B[k,j]
      ΠΊΡ†
      C[i,j] := sum
    ΠΊΡ†
  ΠΊΡ†

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°

АналитичСски $C_{i,j} = \min(i, j) + 1$. Π’ ΠΊΠΎΠ΄Π΅ это Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΎ условиСм: Ссли $i < j$, ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ€Π°Π²Π½ΠΎ $i + 1$, ΠΈΠ½Π°Ρ‡Π΅ $j + 1$. ВычисляСм ΠΎΡˆΠΈΠ±ΠΊΡƒ ΠΈ Π΅Ρ‘ Π½ΠΎΡ€ΠΌΡ‹:

  | ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°: ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ C[i,j] = max(0, i - j + 1)
  res_l2_sq := 0.0
  res_inf := 0.0
  Π½Ρ† для i ΠΎΡ‚ 0 Π΄ΠΎ n-1
    Π½Ρ† для j ΠΎΡ‚ 0 Π΄ΠΎ n-1
      Ссли i < j Ρ‚ΠΎ
        err := C[i,j] - (i + 1.0)
      ΠΈΠ½Π°Ρ‡Π΅
        err := C[i,j] - (j + 1.0)
      всС
      absv := err; Ссли absv < 0.0 Ρ‚ΠΎ absv := -absv всС
      res_l2_sq := res_l2_sq + err * err
      Ссли absv > res_inf Ρ‚ΠΎ res_inf := absv всС
    ΠΊΡ†
  ΠΊΡ†
  res_l2 := sqrt(res_l2_sq)

  Π²Ρ‹Π²ΠΎΠ΄ "matmat: ||e||_2^2 = ", res_l2_sq, нс
  Π²Ρ‹Π²ΠΎΠ΄ "matmat: ||e||_2    = ", res_l2, нс
  Π²Ρ‹Π²ΠΎΠ΄ "matmat: ||e||_inf  = ", res_inf, нс

Π‘Π»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π½Π°ΠΈΠ²Π½ΠΎΠ³ΠΎ умноТСния ΠΌΠ°Ρ‚Ρ€ΠΈΡ† -- $O(n^3)$ (Ρ‚Ρ€ΠΈ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… Ρ†ΠΈΠΊΠ»Π°). Π‘ΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ асимптотичСски Π±ΠΎΠ»Π΅Π΅ быстрыС Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ ШтрассСна со ΡΠ»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒΡŽ $O(n^{2.81})$), Π½ΠΎ Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ для Π½Π΅Π±ΠΎΠ»ΡŒΡˆΠΈΡ… ΠΌΠ°Ρ‚Ρ€ΠΈΡ† Ρ‚Ρ€ΠΎΠΉΠ½ΠΎΠΉ Ρ†ΠΈΠΊΠ» Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ…ΠΎΡ€ΠΎΡˆΠΎ.

Полная ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°

Π°Π»Π³ main
Π½Π°Ρ‡
  | ΠœΠ°Ρ‚ΠΌΠ°Ρ‚Ρ€: C = A * B. A β€” Π½ΠΈΠΆΠ½Π΅Ρ‚Ρ€Π΅ΡƒΠ³ΠΎΠ»ΡŒΠ½Π°Ρ ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π° ΠΈΠ· Π΅Π΄ΠΈΠ½ΠΈΡ†,
  | B β€” Π²Π΅Ρ€Ρ…Π½Π΅Ρ‚Ρ€Π΅ΡƒΠ³ΠΎΠ»ΡŒΠ½Π°Ρ ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π° ΠΈΠ· Π΅Π΄ΠΈΠ½ΠΈΡ†. Π’ΠΎΠ³Π΄Π°
  | C[i,j] = число k, Ρ‚Π°ΠΊΠΈΡ… Ρ‡Ρ‚ΠΎ j <= k <= i = max(0, i - j + 1).

  Ρ†Π΅Π» n,i,j,k
  n := 128
  Π²Π΅Ρ‰ Ρ‚Π°Π± A[0:n-1,0:n-1]
  Π²Π΅Ρ‰ Ρ‚Π°Π± B[0:n-1,0:n-1]
  Π²Π΅Ρ‰ Ρ‚Π°Π± C[0:n-1,0:n-1]
  Π²Π΅Ρ‰ sum, err, absv, res_l2_sq, res_l2, res_inf

  | Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ A (Π½ΠΈΠΆΠ½ΠΈΠΉ Ρ‚Ρ€Π΅ΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ) ΠΈ B (Π²Π΅Ρ€Ρ…Π½ΠΈΠΉ Ρ‚Ρ€Π΅ΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ)
  Π½Ρ† для i ΠΎΡ‚ 0 Π΄ΠΎ n-1
    Π½Ρ† для j ΠΎΡ‚ 0 Π΄ΠΎ n-1
      Ссли j <= i Ρ‚ΠΎ A[i,j] := 1.0 ΠΈΠ½Π°Ρ‡Π΅ A[i,j] := 0.0 всС
      Ссли j >= i Ρ‚ΠΎ B[i,j] := 1.0 ΠΈΠ½Π°Ρ‡Π΅ B[i,j] := 0.0 всС
    ΠΊΡ†
  ΠΊΡ†

  | ВычисляСм C = A * B
  Π½Ρ† для i ΠΎΡ‚ 0 Π΄ΠΎ n-1
    Π½Ρ† для j ΠΎΡ‚ 0 Π΄ΠΎ n-1
      sum := 0.0
      Π½Ρ† для k ΠΎΡ‚ 0 Π΄ΠΎ n-1
        sum := sum + A[i,k] * B[k,j]
      ΠΊΡ†
      C[i,j] := sum
    ΠΊΡ†
  ΠΊΡ†

  | ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°: ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ C[i,j] = max(0, i - j + 1)
  res_l2_sq := 0.0
  res_inf := 0.0
  Π½Ρ† для i ΠΎΡ‚ 0 Π΄ΠΎ n-1
    Π½Ρ† для j ΠΎΡ‚ 0 Π΄ΠΎ n-1
      Ссли i < j Ρ‚ΠΎ
        err := C[i,j] - (i + 1.0)
      ΠΈΠ½Π°Ρ‡Π΅
        err := C[i,j] - (j + 1.0)
      всС
      absv := err; Ссли absv < 0.0 Ρ‚ΠΎ absv := -absv всС
      res_l2_sq := res_l2_sq + err * err
      Ссли absv > res_inf Ρ‚ΠΎ res_inf := absv всС
    ΠΊΡ†
  ΠΊΡ†
  res_l2 := sqrt(res_l2_sq)

  Π²Ρ‹Π²ΠΎΠ΄ "matmat: ||e||_2^2 = ", res_l2_sq, нс
  Π²Ρ‹Π²ΠΎΠ΄ "matmat: ||e||_2    = ", res_l2, нс
  Π²Ρ‹Π²ΠΎΠ΄ "matmat: ||e||_inf  = ", res_inf, нс
ΠΊΠΎΠ½

β–Ά Π—Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€