How to resolve the algorithm Vector products step by step in the JavaScript programming language
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