How to resolve the algorithm Vector products step by step in the JavaScript programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Vector products step by step in the JavaScript programming language

Table of Contents

Problem Statement

A vector is defined as having three dimensions as being represented by an ordered collection of three numbers:   (X, Y, Z). If you imagine a graph with the   x   and   y   axis being at right angles to each other and having a third,   z   axis coming out of the page, then a triplet of numbers,   (X, Y, Z)   would represent a point in the region,   and a vector from the origin to the point. Given the vectors: then the following common vector products are defined:

Given the three vectors:

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Vector products step by step in the JavaScript programming language

Both source codes are implementing vector and scalar operations in Javascript. The first code defines four functions:

  • dotProduct: Computes the dot product of two vectors.
  • crossProduct: Computes the cross product of two 3D vectors.
  • scalarTripleProduct: Computes the scalar triple product of three vectors.
  • vectorTripleProduct: Computes the vector triple product of three vectors.

The second code also defines four functions with the same names, but with different implementations.

The main difference between the two implementations is that the first code uses imperative programming style, while the second code uses functional programming style.

Imperative programming style is a programming style that uses state and mutation. In the first code, the dotProduct function uses a loop to iterate over the elements of the two vectors and compute the sum of the products of the corresponding elements. The crossProduct function uses a loop to iterate over the elements of the two vectors and compute the cross product of the corresponding elements. The scalarTripleProduct function uses a loop to iterate over the elements of the three vectors and compute the scalar triple product. The vectorTripleProduct function uses a loop to iterate over the elements of the three vectors and compute the vector triple product.

Functional programming style is a programming style that uses functions and immutability. In the second code, the dotProduct function uses the zipWith function to iterate over the elements of the two vectors and compute the sum of the products of the corresponding elements. The crossProduct function uses the zipWith function to iterate over the elements of the two vectors and compute the cross product of the corresponding elements. The scalarTripleProduct function uses the bindLR function to compose the crossProduct and dotProduct functions. The vectorTripleProduct function uses the bindLR function to compose the crossProduct function with itself.

Functional programming style is generally considered to be more concise, readable, and maintainable than imperative programming style. However, imperative programming style can be more efficient in some cases.

Source code in the javascript programming language

function dotProduct() {
  var len = arguments[0] && arguments[0].length;
  var argsLen = arguments.length;
  var i, j = len;
  var prod, sum = 0;
  
  // If no arguments supplied, return undefined
  if (!len) {
    return;
  }
  
  // If all vectors not same length, return undefined
  i = argsLen;
  while (i--) {
  
    if (arguments[i].length != len) {
      return;  // return undefined
    }
  }
  
  // Sum terms
  while (j--) {
    i = argsLen;
    prod = 1;
    
    while (i--) {
      prod *= arguments[i][j];
    }
    sum += prod;
  }
  return sum;
}

function crossProduct(a, b) {

  // Check lengths
  if (a.length != 3 || b.length != 3) {
     return;
  }
  
  return [a[1]*b[2] - a[2]*b[1],
          a[2]*b[0] - a[0]*b[2],
          a[0]*b[1] - a[1]*b[0]];
          
}

function scalarTripleProduct(a, b, c) {
  return dotProduct(a, crossProduct(b, c));
}

function vectorTripleProduct(a, b, c) {
  return crossProduct(a, crossProduct(b, c));
}

// Run tests
(function () {
  var a = [3, 4, 5];
  var b = [4, 3, 5];
  var c = [-5, -12, -13];
  
  alert(
    'A . B: ' + dotProduct(a, b) +
    '\n' +
    'A x B: ' + crossProduct(a, b) +
    '\n' +
    'A . (B x C): ' + scalarTripleProduct(a, b, c) +
    '\n' +
    'A x (B x C): ' + vectorTripleProduct(a, b, c)
  ); 
}());


(() => {
    'use strict';

    // dotProduct :: [a] -> [a] -> Either String a
    const dotProduct = xs =>
        // Dot product of two vectors of equal dimension.
        ys => xs.length !== ys.length ? (
            Left('Dot product not defined - vectors differ in dimension.')
        ) : Right(sum(
            zipWith(mul)(Array.from(xs))(Array.from(ys))
        ));

    // crossProduct :: Num a => (a, a, a) -> (a, a, a)
    // Either String -> (a, a, a)
    const crossProduct = xs =>
        // Cross product of two 3D vectors.
        ys => 3 !== xs.length || 3 !== ys.length ? (
            Left('crossProduct is defined only for 3d vectors.')
        ) : Right((() => {
            const [x1, x2, x3] = Array.from(xs);
            const [y1, y2, y3] = Array.from(ys);
            return [
                x2 * y3 - x3 * y2,
                x3 * y1 - x1 * y3,
                x1 * y2 - x2 * y1
            ];
        })());

    // scalarTriple :: Num a => (a, a, a) -> (a, a, a) -> (a, a a) ->
    // Either String -> a
    const scalarTriple = q =>
        // The scalar triple product.
        r => s => bindLR(crossProduct(r)(s))(
            dotProduct(q)
        );

    // vectorTriple :: Num a => (a, a, a) -> (a, a, a) -> (a, a a) ->
    // Either String -> (a, a, a)
    const vectorTriple = q =>
        // The vector triple product.
        r => s => bindLR(crossProduct(r)(s))(
            crossProduct(q)
        );

    // main :: IO ()
    const main = () => {
        // TEST -------------------------------------------
        const
            a = [3, 4, 5],
            b = [4, 3, 5],
            c = [-5, -12, -13],
            d = [3, 4, 5, 6];

        console.log(unlines(
            zipWith(k => f => k + show(
                saturated(f)([a, b, c])
            ))(['a . b', 'a x b', 'a . (b x c)', 'a x (b x c)'])(
                [dotProduct, crossProduct, scalarTriple, vectorTriple]
            )
            .concat([
                'a . d' + show(
                    dotProduct(a)(d)
                ),
                'a . (b x d)' + show(
                    scalarTriple(a)(b)(d)
                )
            ])
        ));
    };


    // GENERIC FUNCTIONS ----------------------------------

    // Left :: a -> Either a b
    const Left = x => ({
        type: 'Either',
        Left: x
    });

    // Right :: b -> Either a b
    const Right = x => ({
        type: 'Either',
        Right: x
    });

    // bindLR (>>=) :: Either a -> (a -> Either b) -> Either b
    const bindLR = m => mf =>
        undefined !== m.Left ? (
            m
        ) : mf(m.Right);

    // either :: (a -> c) -> (b -> c) -> Either a b -> c
    const either = fl => fr => e =>
        'Either' === e.type ? (
            undefined !== e.Left ? (
                fl(e.Left)
            ) : fr(e.Right)
        ) : undefined;

    // identity :: a -> a
    const identity = x => x;

    // mul (*) :: Num a => a -> a -> a
    const mul = a => b => a * b;

    // Curried function -> [Argument] -> a more saturated value
    const saturated = f =>
        // A curried function applied successively to
        // a list of arguments up to, but not beyond,
        // the point of saturation.
        args => 0 < args.length ? (
            args.slice(1).reduce(
                (a, x) => 'function' !== typeof a ? (
                    a
                ) : a(x),
                f(args[0])
            )
        ) : f;

    // show :: Either String a -> String
    const show = x =>
        either(x => ' => ' + x)(
            x => ' = ' + JSON.stringify(x)
        )(x);

    // sum :: [Num] -> Num
    const sum = xs => xs.reduce((a, x) => a + x, 0);

    // unlines :: [String] -> String
    const unlines = xs => xs.join('\n');

    // zipWith:: (a -> b -> c) -> [a] -> [b] -> [c]
    const zipWith = f => xs => ys =>
        xs.slice(
            0, Math.min(xs.length, ys.length)
        ).map((x, i) => f(x)(ys[i]));

    // MAIN ---
    return main();
})();


  

You may also check:How to resolve the algorithm Fibonacci sequence step by step in the Fish programming language
You may also check:How to resolve the algorithm Environment variables step by step in the LSL programming language
You may also check:How to resolve the algorithm Active object step by step in the Phix programming language
You may also check:How to resolve the algorithm Generate Chess960 starting position step by step in the Forth programming language
You may also check:How to resolve the algorithm Averages/Arithmetic mean step by step in the KQL programming language