NAME

inner - compute the inner product of two arrays

SYNOPSIS

arr = arr0.inner(op0, op1, arr1)

DESCRIPTION

The inner() method performs a generalized inner product between arr0 and arr1. It uses op1 (typically a dyadic operator like `*) for element-wise combination and op0 (typically an operator like `+) for reduction.

This is a generalization of matrix multiplication. Specifically, it computes the inner product over the last dimension of arr0 and the first dimension of arr1.

This is similar to APL arr0 op0 . op1 arr1. The inner product is probably the most difficult operation to fully explain. In the simple case of two vectors, it is equivalent to

    (vec0 op1 vec1).reduce(op0)

In APL notation, the operation is defined as

    op0/ ¨(⊂ [⍴⍴ arr0]arr0) ∘. op1 ⊂ [1]arr1

Anybody who finds this definition helpful is already an APL expert and does not need the inner product explained further. However, a more readable algorithm is:

    // Enclose arr0 along the last axis
    var encl0 = arr0.enclose(-1);

    // Enclose arr1 along the first axis
    var encl1 = arr1.enclose(0);

    // Compute outer product of enclosed arrays with second operator
    var out = encl0.outer(op1,encl1);

    // For each element in the outer product, reduce it by the first operator
    var result = new Array(out.shape());
    forall (out#[i]) result#[i] = out#[i].disclose().reduce(op0);

    // Pack the result
    result = result.pack();

    // Convert single-element vector to scalar
    if (result.sizeof() == 1) result = result#[0];

RETURN VALUE

An array representing the inner product of arr0 and arr1. If the result is a single value, it may be returned as a scalar.

ERRORS

ArgCheck if the number of arguments is incorrect.
ShapeCheck if the last dimension of arr0 does not match the first dimension of arr1.

EXAMPLE

    // Dot product of two vectors
    a = [1, 2, 3]
    b = [4, 5, 6]
    c = a.inner(`+, `*, b)
    // c is 1*4 + 2*5 + 3*6 = 32

    // Matrix multiplication
    m1 = [[1, 2], [3, 4]]
    m2 = [[5, 6], [7, 8]]
    m3 = m1.inner(`+, `*, m2)
    // m3 is [[19, 22}, [43, 50}]

SEE ALSO

outer