Dot product

From Rosetta Code
Jump to: navigation, search
Task
Dot product
You are encouraged to solve this task according to the task description, using any language you may know.

Create a function/use an in-built function, to compute the dot product, also known as the scalar product of two vectors. If possible, make the vectors of arbitrary length.

As an example, compute the dot product of the vectors [1, 3, -5] and [4, -2, -1].

If implementing the dot product of two vectors directly, each vector must be the same length; multiply corresponding terms from each vector then sum the results to produce the answer.

Reference

Contents

[edit] ABAP

report zdot_product
data: lv_n type i,
lv_sum type i,
lt_a type standard table of i,
lt_b type standard table of i.
 
append: '1' to lt_a, '3' to lt_a, '-5' to lt_a.
append: '4' to lt_b, '-2' to lt_b, '-1' to lt_b.
describe table lt_a lines lv_n.
 
perform dot_product using lt_a lt_b lv_n changing lv_sum.
 
write lv_sum left-justified.
 
form dot_product using it_a like lt_a
it_b like lt_b
iv_n type i
changing
ev_sum type i.
field-symbols: <wa_a> type i, <wa_b> type i.
 
do iv_n times.
read table: it_a assigning <wa_a> index sy-index, it_b assigning <wa_b> index sy-index.
lv_sum = lv_sum + ( <wa_a> * <wa_b> ).
enddo.
endform.
Output:
3

[edit] ACL2

(defun dotp (v u)
(if (or (endp v) (endp u))
0
(+ (* (first v) (first u))
(dotp (rest v) (rest u)))))
> (dotp '(1 3 -5) '(4 -2 -1))
3

[edit] ActionScript

function dotProduct(v1:Vector.<Number>, v2:Vector.<Number>):Number
{
if(v1.length != v2.length) return NaN;
var sum:Number = 0;
for(var i:uint = 0; i < v1.length; i++)
sum += v1[i]*v2[i];
return sum;
}
trace(dotProduct(Vector.<Number>([1,3,-5]),Vector.<Number>([4,-2,-1])));

[edit] Ada

with Ada.Text_IO; use Ada.Text_IO;
procedure dot_product is
type vect is array(Positive range <>) of Integer;
v1 : vect := (1,3,-5);
v2 : vect := (4,-2,-1);
 
function dotprod(a: vect; b: vect) return Integer is
sum : Integer := 0;
begin
if not (a'Length=b'Length) then raise Constraint_Error; end if;
for p in a'Range loop
sum := sum + a(p)*b(p);
end loop;
return sum;
end dotprod;
 
begin
put_line(Integer'Image(dotprod(v1,v2)));
end dot_product;
Output:
3

[edit] ALGOL 68

Translation of: C++
Works with: ALGOL 68 version Standard - with prelude inserted manually
Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386
Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386
MODE DOTFIELD = REAL;
MODE DOTVEC = [1:0]DOTFIELD;
 
# The "Spread Sheet" way of doing a dot product:
o Assume bounds are equal, and start at 1
o Ignore round off error
#

PRIO SSDOT = 7;
OP SSDOT = (DOTVEC a,b)DOTFIELD: (
DOTFIELD sum := 0;
FOR i TO UPB a DO sum +:= a[i]*b[i] OD;
sum
);
 
# An improved dot-product version:
o Handles sparse vectors
o Improves summation by gathering round off error
with no additional multiplication - or LONG - operations.
#

OP * = (DOTVEC a,b)DOTFIELD: (
DOTFIELD sum := 0, round off error:= 0;
FOR i
# Assume bounds may not be equal, empty members are zero (sparse) #
FROM LWB (LWB a > LWB b | a | b )
TO UPB (UPB a < UPB b | a | b )
DO
DOTFIELD org = sum, prod = a[i]*b[i];
sum +:= prod;
round off error +:= sum - org - prod
OD;
sum - round off error
);
 
# Test: #
DOTVEC a=(1,3,-5), b=(4,-2,-1);
 
print(("a SSDOT b = ",fixed(a SSDOT b,0,real width), new line));
print(("a * b = ",fixed(a * b,0,real width), new line))
Output:
a SSDOT b = 3.000000000000000

a   *   b = 3.000000000000000

[edit] AutoHotkey

Vet1 := "1,3,-5"
Vet2 := "4 , -2 , -1"
MsgBox % DotProduct( Vet1 , Vet2 )
 
;---------------------------
 
DotProduct( VectorA , VectorB )
{
Sum := 0
StringSplit, ArrayA, VectorA, `,, %A_Space%
StringSplit, ArrayB, VectorB, `,, %A_Space%
If ( ArrayA0 <> ArrayB0 )
Return ERROR
While ( A_Index <= ArrayA0 )
Sum += ArrayA%A_Index% * ArrayB%A_Index%
Return Sum
}

[edit] AWK

 
# syntax: GAWK -f DOT_PRODUCT.AWK
BEGIN {
v1 = "1,3,-5"
v2 = "4,-2,-1"
if (split(v1,v1arr,",") != split(v2,v2arr,",")) {
print("error: vectors are of unequal lengths")
exit(1)
}
printf("%g\n",dot_product(v1arr,v2arr))
exit(0)
}
function dot_product(v1,v2, i,sum) {
for (i in v1) {
sum += v1[i] * v2[i]
}
return(sum)
}
 
Output:
3

[edit] BBC BASIC

BBC BASIC has a built-in dot-product operator:

      DIM vec1(2), vec2(2), dot(0)
 
vec1() = 1, 3, -5
vec2() = 4, -2, -1
 
dot() = vec1() . vec2()
PRINT "Result is "; dot(0)
Output:
Result is 3

[edit] bc

/* Calculate the dot product of two vectors a and b (represented as
* arrays) of size n.
*/
define d(a[], b[], n) {
auto d, i
 
for (i = 0; i < n; i++) {
d += a[i] * b[i]
}
return(d)
}
 
a[0] = 1
a[1] = 3
a[2] = -5
b[0] = 4
b[1] = -2
b[2] = -1
d(a[], b[], 3)
Output:
3

[edit] Befunge 93

 
v Space for variables
v Space for vector1
v Space for vector2
v http://rosettacode.org/wiki/Dot_product
>00pv
>>55+":htgneL",,,,,,,,&:0` |
v,,,,,,,"Length can't be negative."+55<
>,,,,,,,,,,,,,,,,,,,@ |!`-10<
>0.@
v,")".g00,,,,,,,,,,,,,,"Vector a(size " <
0v01g00,")".g00,,,,,,,,,,,,,,"Vector b"<
0pvp2g01&p01-1g01< "
g>> 10g0`| @.g30<(
1 >03g:-03p>00g1-` |s
0 vp00-1g00p30+g30*g2-1g00g1-1g00<i
p > v # z
vp1g01&p01-1g01<> ^ e
> 10g0` | vp01-1g01.g1<
>00g1-10p>10g:01-` | "
> ^
 
Output:
Length:

3 Vector a(size 3 )1 3 -5 1 3 -5 Vector b(size 3 )4 -2 -1

3

[edit] Bracmat

  ( dot
= a A z Z
.  !arg:(%?a ?z.%?A ?Z)
& !a*!A+dot$(!z.!Z)
| 0
)
& out$(dot$(1 3 -5.4 -2 -1));
Output:
3

[edit] C

#include <stdio.h>
#include <stdlib.h>
 
int dot_product(int *, int *, size_t);
 
int
main(void)
{
int a[3] = {1, 3, -5};
int b[3] = {4, -2, -1};
 
printf("%d\n", dot_product(a, b, sizeof(a) / sizeof(a[0])));
 
return EXIT_SUCCESS;
}
 
int
dot_product(int *a, int *b, size_t n)
{
int sum = 0;
size_t i;
 
for (i = 0; i < n; i++) {
sum += a[i] * b[i];
}
 
return sum;
}
Output:
3

[edit] C#

static void Main(string[] args)
{
Console.WriteLine(DotProduct(new decimal[] { 1, 3, -5 }, new decimal[] { 4, -2, -1 }));
Console.Read();
}
 
private static decimal DotProduct(decimal[] vec1, decimal[] vec2)
{
if (vec1 == null)
return 0;
 
if (vec2 == null)
return 0;
 
if (vec1.Length != vec2.Length)
return 0;
 
decimal tVal = 0;
for (int x = 0; x < vec1.Length; x++)
{
tVal += vec1[x] * vec2[x];
}
 
return tVal;
}
Output:
3

[edit] Alternative using Linq (C# 4)

Works with: C# version 4
public static decimal DotProduct(decimal[] a, decimal[] b) {
return a.Zip(b, (x, y) => x * y).Sum();
}

[edit] C++

#include <iostream>
#include <numeric>
 
int main()
{
int a[] = { 1, 3, -5 };
int b[] = { 4, -2, -1 };
 
std::cout << std::inner_product(a, a + sizeof(a) / sizeof(a[0]), b, 0) << std::endl;
 
return 0;
}
Output:
3

[edit] Clojure

Works with: Clojure version 1.1

Preconditions are new in 1.1. The actual code also works in older Clojure versions.

(defn dot-product [& matrix]
{:pre [(apply == (map count matrix))]}
(apply + (apply map * matrix)))
 
;Example Usage
(println (dot-product [1 3 -5] [4 -2 -1]))

[edit] CoffeeScript

dot_product = (ary1, ary2) ->
if ary1.length != ary2.length
throw "can't find dot product: arrays have different lengths"
dotprod = 0
for v, i in ary1
dotprod += v * ary2[i]
dotprod
 
console.log dot_product([ 1, 3, -5 ], [ 4, -2, -1 ]) # 3
try
console.log dot_product([ 1, 3, -5 ], [ 4, -2, -1, 0 ]) # exception
catch e
console.log e
Output:
> coffee foo.coffee 

3

can't find dot product: arrays have different lengths

[edit] Common Lisp

(defun dot-product (a b)
(apply #'+ (mapcar #'* (coerce a 'list) (coerce b 'list))))

This works with any size vector, and (as usual for Common Lisp) all numeric types (rationals, bignums, complex numbers, etc.).

Maybe it is better to do it without coercing. Then we got a cleaner code.

(defun dot-prod (a b)
(reduce #'+ (map 'simple-vector #'* a b)))

[edit] D

void main() {
import std.stdio, std.numeric;
 
[1.0, 3.0, -5.0].dotProduct([4.0, -2.0, -1.0]).writeln;
}
Output:
3

Using an array operation:

void main() {
import std.stdio, std.algorithm;
 
double[3] a = [1.0, 3.0, -5.0];
double[3] b = [4.0, -2.0, -1.0];
double[3] c = a[] * b[];
c[].sum.writeln;
}

[edit] Dart

num dot(List<num> A, List<num> B){
if (A.length != B.length){
throw new Exception('Vectors must be of equal size');
}
num result = 0;
for (int i = 0; i < A.length; i++){
result += A[i] * B[i];
}
return result;
}
 
void main(){
var l = [1,3,-5];
var k = [4,-2,-1];
print(dot(l,k));
}
Output:
3

[edit] Delphi

Works with: Lazarus
program Project1;
 
{$APPTYPE CONSOLE}
 
type
doublearray = array of Double;
 
function DotProduct(const A, B : doublearray): Double;
var
I: integer;
begin
assert (Length(A) = Length(B), 'Input arrays must be the same length');
Result := 0;
for I := 0 to Length(A) - 1 do
Result := Result + (A[I] * B[I]);
end;
 
var
x,y: doublearray;
begin
SetLength(x, 3);
SetLength(y, 3);
x[0] := 1; x[1] := 3; x[2] := -5;
y[0] := 4; y[1] :=-2; y[2] := -1;
WriteLn(DotProduct(x,y));
ReadLn;
end.
Output:
 3.00000000000000E+0000

Note: Delphi does not like arrays being declared in procedure headings, so it is necessary to declare it beforehand. To use integers, modify doublearray to be an array of integer.

[edit] Déjà Vu

dot a b:
if /= len a len b:
Raise value-error "dot product needs two vectors with the same length"
 
0
while a:
+ * pop-from a pop-from b
 
!. dot [ 1 3 -5 ] [ 4 -2 -1 ]
Output:
3

[edit] DWScript

For arbitrary length vectors, using a precondition to check vector length:

function DotProduct(a, b : array of Float) : Float;
require
a.Length = b.Length;
var
i : Integer;
begin
Result := 0;
for i := 0 to a.High do
Result += a[i]*b[i];
end;
 
PrintLn(DotProduct([1,3,-5], [4,-2,-1]));

Using built-in 4D Vector type:

var a := Vector(1, 3, -5, 0);
var b := Vector(4, -2, -1, 0);
 
PrintLn(a * b);
Ouput in both cases:
3

[edit] Ela

Translation of: Haskell
open list
 
dotp a b | length a == length b = sum (zipWith (*) a b)
| else = fail "Vector sizes must match."
 
dotp [1,3,-5] [4,-2,-1]
Output:
3

[edit] Erlang

dotProduct(A,B) when length(A) == length(B) -> dotProduct(A,B,0);
dotProduct(_,_) -> erlang:error('Vectors must have the same length.').
 
dotProduct([H1|T1],[H2|T2],P) -> dotProduct(T1,T2,P+H1*H2);
dotProduct([],[],P) -> P.
 
dotProduct([1,3,-5],[4,-2,-1]).
Output:
3

[edit] Euphoria

function dotprod(sequence a, sequence b)
atom sum
a *= b
sum = 0
for n = 1 to length(a) do
sum += a[n]
end for
return sum
end function
 
? dotprod({1,3,-5},{4,-2,-1})
Output:
3
-- Here is an alternative method,
-- using the standard Euphoria Version 4+ Math Library
include std/math.e
sequence a = {1,3,-5}, b = {4,-2,-1} -- Make them any length you want
? sum(a * b)
Output:
3

[edit] F#

let dot_product (a:array<'a>) (b:array<'a>) =
if Array.length a <> Array.length b then failwith "invalid argument: vectors must have the same lengths"
Array.fold2 (fun acc i j -> acc + (i * j)) 0 a b
> dot_product [| 1; 3; -5 |] [| 4; -2; -1 |] ;;
val it : int = 3

[edit] Factor

The built-in word v. is used to compute the dot product. It doesn't enforce that the vectors are of the same length, so here's a wrapper.

USING: kernel math.vectors sequences ;
 
: dot-product ( u v -- w )
2dup [ length ] bi@ =
[ v. ] [ "Vector lengths must be equal" throw ] if ;
( scratchpad ) { 1 3 -5 } { 4 -2 -1 } dot-product .
3

[edit] FALSE

[[\1-$0=~][$d;2*1+\-ø\$d;2+\-ø@*@+]#]p:
3d: {Vectors' length}
1 3 5_ 4 2_ 1_ d;$1+ø@*p;!%. {Output: 3}

[edit] Fantom

Dot product of lists of Int:

class DotProduct
{
static Int dotProduct (Int[] a, Int[] b)
{
Int result := 0
[a.size,b.size].min.times |i|
{
result += a[i] * b[i]
}
return result
}
 
public static Void main ()
{
Int[] x := [1,2,3,4]
Int[] y := [2,3,4]
 
echo ("Dot product of $x and $y is ${dotProduct(x, y)}")
}
}

[edit] Forth

: vector create cells allot ;
: th cells + ;
 
3 constant /vector
/vector vector a
/vector vector b
 
: dotproduct ( a1 a2 -- n)
0 tuck ?do -rot over i th @ over i th @ * >r rot r> + loop nip nip
;
 
: vector! cells over + swap ?do i ! 1 cells +loop ;
 
-5 3 1 a /vector vector!
-1 -2 4 b /vector vector!
 
a b /vector dotproduct . 3 ok

[edit] Fortran

Works with: Fortran version 90 and later
program test_dot_product
 
write (*, '(i0)') dot_product ((/1, 3, -5/), (/4, -2, -1/))
 
end program test_dot_product
Output:
3

[edit] FunL

import lists.zipWith
 
def dot( a, b )
| a.length() == b.length() = sum( zipWith((*), a, b) )
| otherwise = error( "Vector sizes must match" )
 
println( dot([1, 3, -5], [4, -2, -1]) )
Output:
3

[edit] GAP

# Built-in
 
[1, 3, -5]*[4, -2, -1];
# 3

[edit] Go

package main
 
import (
"errors"
"fmt"
)
 
func dot(x, y []int) (r int, err error) {
if len(x) != len(y) {
return 0, errors.New("incompatible lengths")
}
for i := range x {
r += x[i] * y[i]
}
return
}
 
func main() {
d, err := dot([]int{1, 3, -5}, []int{4, -2, -1})
if err != nil {
fmt.Println(err)
return
}
fmt.Println(d)
}
Output:
3

[edit] Groovy

Solution:

def dotProduct = { x, y ->
assert x && y && x.size() == y.size()
[x, y].transpose().collect{ it[0] * it[1] }.sum()
}

Test:

println dotProduct([1, 3, -5], [4, -2, -1])
Output:
3

[edit] Haskell

dotp a b | length a == length b = sum (zipWith (*) a b)
| otherwise = error "Vector sizes must match"
 
main = print $ dotp [1, 3, -5] [4, -2, -1] -- prints 3

[edit] Icon and Unicon

The procedure below computes the dot product of two vectors of arbitrary length or generates a run time error if its arguments are the wrong type or shape.

procedure main()
write("a dot b := ",dotproduct([1, 3, -5],[4, -2, -1]))
end
 
procedure dotproduct(a,b) #: return dot product of vectors a & b or error
if *a ~= *b & type(a) == type(b) == "list" then runerr(205,a) # invalid value
every (dp := 0) +:= a[i := 1 to *a] * b[i]
return dp
end

[edit] IDL

 
a = [1, 3, -5]
b = [4, -2, -1]
c = a#TRANSPOSE(b)
c = TOTAL(a*b,/PRESERVE_TYPE)
 

[edit] J

   1 3 _5  +/ . * 4 _2 _1
3
dotp=: +/ . * NB. Or defined as a verb (function)
1 3 _5 dotp 4 _2 _1
3

Note also: The verbs built using the conjunction . generally apply to matricies and arrays of higher dimensions and can be built with verbs (functions) other than sum ( +/ ) and product ( * ).

[edit] Java

public class DotProduct {
 
public static void main(String[] args) {
double[] a = {1, 3, -5};
double[] b = {4, -2, -1};
 
System.out.println(dotProd(a,b));
}
 
public static double dotProd(double[] a, double[] b){
if(a.length != b.length){
throw new IllegalArgumentException("The dimensions have to be equal!");
}
double sum = 0;
for(int i = 0; i < a.length; i++){
sum += a[i] * b[i];
}
return sum;
}
}
Output:
3.0

[edit] JavaScript

function dot_product(ary1, ary2) {
if (ary1.length != ary2.length)
throw "can't find dot product: arrays have different lengths";
var dotprod = 0;
for (var i = 0; i < ary1.length; i++)
dotprod += ary1[i] * ary2[i];
return dotprod;
}
 
print(dot_product([1,3,-5],[4,-2,-1])); // ==> 3
print(dot_product([1,3,-5],[4,-2,-1,0])); // ==> exception

[edit] jq

The dot-product of two arrays, x and y, can be computed using dot(x;y) defined as follows:

 
def dot(x; y):
reduce range(0;x|length) as $i (0; . + x[$i] * y[$i]);
 

Suppose however that we are given an array of objects, each of which has an "x" field and a "y" field, and that we wish to compute SIGMA( x * y ) where the sum is taken over the array, and where x and y denote the values in the "x" and "y" fields respectively.

This can most usefully be accomplished in jq with the aid of SIGMA(f) defined as follows:
def SIGMA( f ): reduce .[] as $o (0; . + ($o | f )) ;

Given the array of objects as input, the dot-product is then simply SIGMA( .x * .y ).

Example:
dot( [1, 3, -5]; [4, -2, -1]) # => 3
 
[ {"x": 1, "y": 4}, {"x": 3, "y": -2}, {"x": -5, "y": -1} ]
| SIGMA( .x * .y ) # => 3

[edit] Julia

Dot products and many other linear-algebra functions are built-in functions in Julia (and are largely implemented by calling functions from LAPACK).

x = [1, 3, -5]
y = [4, -2, -1]
z = dot(x, y)

[edit] K

   +/1 3 -5 * 4 -2 -1
3
 
1 3 -5 _dot 4 -2 -1
3

[edit] LFE

(defun dot-product (a b)
(: lists foldl #'+/2 0
(: lists zipwith #'*/2 a b)))
 

[edit] Liberty BASIC

vectorA$ = "1, 3, -5"
vectorB$ = "4, -2, -1"
print "DotProduct of ";vectorA$;" and "; vectorB$;" is ";
print DotProduct(vectorA$, vectorB$)
 
'arbitrary length
vectorA$ = "3, 14, 15, 9, 26"
vectorB$ = "2, 71, 18, 28, 1"
print "DotProduct of ";vectorA$;" and "; vectorB$;" is ";
print DotProduct(vectorA$, vectorB$)
 
end
 
function DotProduct(a$, b$)
DotProduct = 0
i = 1
while 1
x$=word$( a$, i, ",")
y$=word$( b$, i, ",")
if x$="" or y$="" then exit function
DotProduct = DotProduct + val(x$)*val(y$)
i = i+1
wend
end function

[edit]

to dotprod :a :b
output apply "sum (map "product :a :b)
end
 
show dotprod [1 3 -5] [4 -2 -1]  ; 3

[edit] Logtalk

dot_product(A, B, Sum) :-
dot_product(A, B, 0, Sum).
 
dot_product([], [], Sum, Sum).
dot_product([A| As], [B| Bs], Acc, Sum) :-
Acc2 is Acc + A*B,
dot_product(As, Bs, Acc2, Sum).

[edit] Lua

function dotprod(a, b)
local ret = 0
for i = 1, #a do
ret = ret + a[i] * b[i]
end
return ret
end
 
print(dotprod({1, 3, -5}, {4, -2, 1}))

[edit] Maple

Between Arrays, Vectors, or Matrices you can use the dot operator:

<1,2,3> . <4,5,6>
Array([1,2,3]) . Array([4,5,6])

Between any of the above or lists, you can use the LinearAlgebra[DotProduct] function:

LinearAlgebra( <1,2,3>, <4,5,6> )
LinearAlgebra( Array([1,2,3]), Array([4,5,6]) )
LinearAlgebra([1,2,3], [4,5,6] )

[edit] Mathematica

{1,3,-5}.{4,-2,-1}

[edit] MATLAB

The dot product operation is a built-in function that operates on vectors of arbitrary length.

A = [1 3 -5]
B = [4 -2 -1]
C = dot(A,B)

For the Octave implimentation:

function C = DotPro(A,B)
C = sum( A.*B );
end

[edit] Maxima

[1, 3, -5] . [4, -2, -1];
/* 3 */

[edit] Mercury

This will cause a software_error/1 exception if the lists are of different lengths.

:- module dot_product.
:- interface.
 
:- import_module io.
:- pred main(io::di, io::uo) is det.
 
:- implementation.
:- import_module int, list.
 
main(!IO) :-
io.write_int([1, 3, -5] `dot_product` [4, -2, -1], !IO),
io.nl(!IO).
 
:- func dot_product(list(int), list(int)) = int.
 
dot_product(As, Bs) =
list.foldl_corresponding((func(A, B, Acc) = Acc + A * B), As, Bs, 0).

[edit] МК-61/52

С/П	*	ИП0	+	П0	С/П	БП	00

Input: В/О x1 С/П x2 С/П y1 С/П y2 С/П ...

[edit] MUMPS

DOTPROD(A,B)
 ;Returns the dot product of two vectors. Vectors are assumed to be stored as caret-delimited strings of numbers.
 ;If the vectors are not of equal length, a null string is returned.
QUIT:$LENGTH(A,"^")'=$LENGTH(B,"^") ""
NEW I,SUM
SET SUM=0
FOR I=1:1:$LENGTH(A,"^") SET SUM=SUM+($PIECE(A,"^",I)*$PIECE(B,"^",I))
KILL I
QUIT SUM

[edit] Nemerle

This will cause an exception if the arrays are different lengths.

using System;
using System.Console;
using Nemerle.Collections.NCollectionsExtensions;
 
module DotProduct
{
DotProduct(x : array[int], y : array[int]) : int
{
$[(a * b)|(a, b) in ZipLazy(x, y)].FoldLeft(0, _+_);
}
 
Main() : void
{
def arr1 = array[1, 3, -5]; def arr2 = array[4, -2, -1];
WriteLine(DotProduct(arr1, arr2));
}
}

[edit] NetRexx

/* NetRexx */
options replace format comments java crossref savelog symbols binary
 
whatsTheVectorVictor = [[double 1.0, 3.0, -5.0], [double 4.0, -2.0, -1.0]]
dotProduct = Rexx dotProduct(whatsTheVectorVictor)
say dotProduct.format(null, 2)
 
return
 
method dotProduct(vec1 = double[], vec2 = double[]) public constant returns double signals IllegalArgumentException
if vec1.length \= vec2.length then signal IllegalArgumentException('Vectors must be the same length')
 
scalarProduct = double 0.0
loop e_ = 0 to vec1.length - 1
scalarProduct = vec1[e_] * vec2[e_] + scalarProduct
end e_
 
return scalarProduct
 
method dotProduct(vecs = double[,]) public constant returns double signals IllegalArgumentException
return dotProduct(vecs[0], vecs[1])

[edit] newLISP

(define (dot-product x y) 
(apply + (map * x y)))
 
(println (dot-product '(1 3 -5) '(4 -2 -1)))

[edit] Nimrod

# Compile time error when a and b are differently sized arrays
# Runtime error when a and b are differently sized seqs
proc dotp[T](a,b: T): int =
assert a.len == b.len
for i in a.low..a.high:
result += a[i] * b[i]
 
echo dotp([1,3,-5], [4,-2,-1])
echo dotp(@[1,2,3],@[4,5,6])

[edit] Objective-C

#import <stdio.h>
#import <stdint.h>
#import <stdlib.h>
#import <string.h>
#import <Foundation/Foundation.h>
 
// this class exists to return a result between two
// vectors: if vectors have different "size", valid
// must be NO
@interface VResult : NSObject
{
@private
double value;
BOOL valid;
}
+(instancetype)new: (double)v isValid: (BOOL)y;
-(instancetype)init: (double)v isValid: (BOOL)y;
-(BOOL)isValid;
-(double)value;
@end
 
@implementation VResult
+(instancetype)new: (double)v isValid: (BOOL)y
{
return [[self alloc] init: v isValid: y];
}
-(instancetype)init: (double)v isValid: (BOOL)y
{
if ((self == [super init])) {
value = v;
valid = y;
}
return self;
}
-(BOOL)isValid { return valid; }
-(double)value { return value; }
@end
 
 
@interface RCVector : NSObject
{
@private
double *vec;
uint32_t size;
}
+(instancetype)newWithArray: (double *)v ofLength: (uint32_t)l;
-(instancetype)initWithArray: (double *)v ofLength: (uint32_t)l;
-(VResult *)dotProductWith: (RCVector *)v;
-(uint32_t)size;
-(double *)array;
-(void)free;
@end
 
@implementation RCVector
+(instancetype)newWithArray: (double *)v ofLength: (uint32_t)l
{
return [[self alloc] initWithArray: v ofLength: l];
}
-(instancetype)initWithArray: (double *)v ofLength: (uint32_t)l
{
if ((self = [super init])) {
size = l;
vec = malloc(sizeof(double) * l);
if ( vec == NULL )
return nil;
memcpy(vec, v, sizeof(double)*l);
}
return self;
}
-(void)dealloc
{
free(vec);
}
-(uint32_t)size { return size; }
-(double *)array { return vec; }
-(VResult *)dotProductWith: (RCVector *)v
{
double r = 0.0;
uint32_t i, s;
double *v1;
if ( [self size] != [v size] ) return [VResult new: r isValid: NO];
s = [self size];
v1 = [v array];
for(i = 0; i < s; i++) {
r += vec[i] * v1[i];
}
return [VResult new: r isValid: YES];
}
@end
 
double val1[] = { 1, 3, -5 };
double val2[] = { 4,-2, -1 };
 
int main()
{
@autoreleasepool {
RCVector *v1 = [RCVector newWithArray: val1 ofLength: sizeof(val1)/sizeof(double)];
RCVector *v2 = [RCVector newWithArray: val2 ofLength: sizeof(val1)/sizeof(double)];
VResult *r = [v1 dotProductWith: v2];
if ( [r isValid] ) {
printf("%lf\n", [r value]);
} else {
fprintf(stderr, "length of vectors differ\n");
}
}
return 0;
}

[edit] Objeck

bundle Default {
class DotProduct {
function : Main(args : String[]) ~ Nil {
DotProduct([1, 3, -5], [4, -2, -1])->PrintLine();
}
 
function : DotProduct(array_a : Int[], array_b : Int[]) ~ Int {
if(array_a = Nil) {
return 0;
};
 
if(array_b = Nil) {
return 0;
};
 
if(array_a->Size() <> array_b->Size()) {
return 0;
};
 
val := 0;
for(x := 0; x < array_a->Size(); x += 1;) {
val += (array_a[x] * array_b[x]);
};
 
return val;
}
}
}

[edit] OCaml

With lists:

let dot = List.fold_left2 (fun z x y -> z +. x *. y) 0.
 
(*
# dot [1.0; 3.0; -5.0] [4.0; -2.0; -1.0];;
- : float = 3.
*)

With arrays:

let dot v u =
if Array.length v <> Array.length u
then invalid_arg "Different array lengths";
let times v u =
Array.mapi (fun i v_i -> v_i *. u.(i)) v
in Array.fold_left (+.) 0. (times v u)
 
(*
# dot [| 1.0; 3.0; -5.0 |] [| 4.0; -2.0; -1.0 |];;
- : float = 3.
*)

[edit] Octave

See Dot product#MATLAB for an implementation. If we have a row-vector and a column-vector, we can use simply *.

a = [1, 3, -5]
b = [4, -2, -1] % or [4; -2; -1] and avoid transposition with '
disp( a * b' ) % ' means transpose

[edit] Oz

Vectors are represented as lists in this example.

declare
fun {DotProduct Xs Ys}
{Length Xs} = {Length Ys} %% assert
{List.foldL {List.zip Xs Ys Number.'*'} Number.'+' 0}
end
in
{Show {DotProduct [1 3 ~5] [4 ~2 ~1]}}

[edit] PARI/GP

dot(u,v)={
sum(i=1,#u,u[i]*v[i])
};

[edit] Pascal

See Delphi

[edit] Perl

sub dotprod
{
my($vec_a, $vec_b) = @_;
die "they must have the same size\n" unless @$vec_a == @$vec_b;
my $sum = 0;
$sum += $vec_a->[$_] * $vec_b->[$_] for 0..$#$vec_a;
return $sum;
}
 
my @vec_a = (1,3,-5);
my @vec_b = (4,-2,-1);
 
print dotprod(\@vec_a,\@vec_b), "\n"; # 3

[edit] Perl 6

Works with: Rakudo version 2010.07

We use the square-bracket meta-operator to turn the infix operator + into a reducing list operator, and the guillemet meta-operator to vectorize the infix operator *. Length validation is automatic in this form.

say [+] (1, 3, -5) »*« (4, -2, -1);

[edit] PHP

<?php
function dot_product($v1, $v2) {
if (count($v1) != count($v2))
throw new Exception('Arrays have different lengths');
return array_sum(array_map('bcmul', $v1, $v2));
}
 
echo dot_product(array(1, 3, -5), array(4, -2, -1)), "\n";
?>

[edit] PicoLisp

(de dotProduct (A B)
(sum * A B) )
 
(dotProduct (1 3 -5) (4 -2 -1))
Output:
-> 3

[edit] PL/I

get (n);
begin;
declare (A(n), B(n)) float;
declare dot_product float;
 
get list (A);
get list (B);
dot_product = sum(a*b);
put (dot_product);
end;

[edit] PostScript

/dotproduct{
/x exch def
/y exch def
/sum 0 def
/i 0 def
x length y length eq %Check if both arrays have the same length
{
x length{
/sum x i get y i get mul sum add def
/i i 1 add def
}repeat
sum ==
}
{
-1 ==
}ifelse
}def

[edit] Prolog

Works with SWI-Prolog.

dot_product(L1, L2, N) :-
maplist(mult, L1, L2, P),
sumlist(P, N).
 
mult(A,B,C) :-
C is A*B.

Example :

 ?- dot_product([1,3,-5], [4,-2,-1], N).
N = 3.

[edit] PureBasic

Procedure dotProduct(Array a(1),Array b(1))
Protected i, sum, length = ArraySize(a())
 
If ArraySize(a()) = ArraySize(b())
For i = 0 To length
sum + a(i) * b(i)
Next
EndIf
 
ProcedureReturn sum
EndProcedure
 
If OpenConsole()
Dim a(2)
Dim b(2)
 
a(0) = 1 : a(1) = 3 : a(2) = -5
b(0) = 4 : b(1) = -2 : b(2) = -1
 
PrintN(Str(dotProduct(a(),b())))
 
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf

[edit] Python

def dotp(a,b):
assert len(a) == len(b), 'Vector sizes must match'
return sum(aterm * bterm for aterm,bterm in zip(a, b))
 
if __name__ == '__main__':
a, b = [1, 3, -5], [4, -2, -1]
assert dotp(a,b) == 3

[edit] R

Here are several ways to do the task.

x <- c(1, 3, -5)
y <- c(4, -2, -1)
 
sum(x*y) # compute products, then do the sum
x %*% y # inner product
 
# loop implementation
dotp <- function(x, y) {
n <- length(x)
if(length(y) != n) stop("invalid argument")
s <- 0
for(i in 1:n) s <- s + x[i]*y[i]
s
}
 
dotp(x, y)

[edit] Racket

 
#lang racket
(define (dot-product l r) (for/sum ([x l] [y r]) (* x y)))
 
(dot-product '(1 3 -5) '(4 -2 -1))
 
;; dot-product works on sequences such as vectors:
(dot-product #(1 2 3) #(4 5 6))
 

[edit] Rascal

import List;
 
public int dotProduct(list[int] L, list[int] M){
result = 0;
if(size(L) == size(M)) {
while(size(L) >= 1) {
result += (head(L) * head(M));
L = tail(L);
M = tail(M);
}
return result;
}
else {
throw "vector sizes must match";
}
}

[edit] Alternative solution

If a matrix is represented by a relation of <x-coordinate, y-coordinate, value>, then function below can be used to find the Dot product.

import Prelude;
 
public real matrixDotproduct(rel[real x, real y, real v] column1, rel[real x, real y, real v] column2){
return (0.0 | it + v1*v2 | <x1,y1,v1> <- column1, <x2,y2,v2> <- column2, y1==y2);
}
 
//a matrix, given by a relation of x-coordinate, y-coordinate, value.
public rel[real x, real y, real v] matrixA = {
<0.0,0.0,12.0>, <0.0,1.0, 6.0>, <0.0,2.0,-4.0>,
<1.0,0.0,-51.0>, <1.0,1.0,167.0>, <1.0,2.0,24.0>,
<2.0,0.0,4.0>, <2.0,1.0,-68.0>, <2.0,2.0,-41.0>
};

[edit] REBOL

rebol []
 
a: [1 3 -5]
b: [4 -2 -1]
 
dot-product: function [v1 v2] [sum] [
if (length? v1) != (length? v2) [
make error! "error: vector sizes must match"
]
sum: 0
repeat i length? v1 [
sum: sum + ((pick v1 i) * (pick v2 i))
]
]
 
dot-product a b

[edit] REXX

Checks could've been added to the REXX code to ensure that the vector elements are numeric.

/*REXX program computes the  dot product  of  two equal size vectors.   */
vectorA = ' 1 3 -5 ' /*populate vectorA with numbers, */
vectorB = ' 4 -2 -1 ' /* ∙∙∙ and the same for vectorB. */
say /*display a blank line. */
say 'vector A = ' vectorA /*echo the elements in vector A. */
say 'vector B = ' vectorB /* " " " " " B. */
say /*display another blank line. */
p = dotProd(vectorA, vectorB) /*go and compute the dot product.*/
say 'dot product = ' p /*show and tell the dot product. */
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────DOTPROD subroutine──────────────────*/
dotProd: procedure; parse arg A,B /*compute the dot product. */
lenA = words(A) /*number of numbers in vector A.*/
lenB = words(B) /* " " " " " B.*/
if lenA\==lenB then do /*are vectors unequal in size? */
say '*** error! ***'
say "vectors aren't the same size:"
say ' vector A length = ' lenA
say ' vector B length = ' lenB
exit 13 /*exit with return code 13. */
end
sum=0 /*initialize the sum to 0 (zero).*/
do j=1 for lenA /*multiply each number in vectors*/
sum=sum+word(A,j)*word(B,j) /*∙∙∙ and add the product to SUM.*/
end /*j*/
return sum /*return the SUM to the invoker. */

output using the default input:

vector A =   1   3  -5
vector B =   4  -2  -1

dot product =  3

[edit] RLaB

In its simplest form dot product is a composition of two functions: element-by-element multiplication '.*' followed by sumation of an array. Consider an example:

x = rand(1,10);
y = rand(1,10);
s = sum( x .* y );

Warning: element-by-element multiplication is matrix optimized. As the interpretation of the matrix optimization is quite general, and unique to RLaB, any two matrices can be so multiplied irrespective of their dimensions. It is up to user to check whether in his/her case the matrix optimization needs to be restricted, and then to implement restrictions in his/her code.

[edit] Ruby

With the standard library, require 'matrix' and call Vector#inner_product.

irb(main):001:0> require 'matrix'
=> true
irb(main):002:0> Vector[1, 3, -5].inner_product Vector[4, -2, -1]
=> 3

Or implement dot product.

class Array
def dot_product(other)
raise "not the same size!" if self.length != other.length
self.zip(other).inject(0) {|dp, (a, b)| dp += a*b}
end
end
 
p [1, 3, -5].dot_product [4, -2, -1] # => 3


[edit] Run BASIC

v1$ = "1, 3, -5"
v2$ = "4, -2, -1"
 
print "DotProduct of ";v1$;" and "; v2$;" is ";dotProduct(v1$,v2$)
end
 
function dotProduct(a$, b$)
while word$(a$,i + 1,",") <> ""
i = i + 1
v1$=word$(a$,i,",")
v2$=word$(b$,i,",")
dotProduct = dotProduct + val(v1$) * val(v2$)
wend
end function

[edit] Rust

Implemented as a simple function.

fn dot_product(a: Vec<int>, b: Vec<int>) -> int {
let mut s = 0;
for i in range(0, a.len()) {
s += a[i] * b[i];
}
return s;
}
 
fn main() {
let v1 = vec!(1, 3, -5);
let v2 = vec!(4, -2, -1);
 
println!("{}", dot_product(v1, v2));
}

[edit] Sather

Built-in class VEC "implements" euclidean (geometric) vectors.

class MAIN is
main is
x ::= #VEC(|1.0, 3.0, -5.0|);
y ::= #VEC(|4.0, -2.0, -1.0|);
#OUT + x.dot(y) + "\n";
end;
end;

[edit] Scala

Library: Scala
class Dot[T](v1: Seq[T])(implicit n: Numeric[T]) {
import n._ // import * operator
def dot(v2: Seq[T]) = {
require(v1.size == v2.size)
(v1 zip v2).map{ Function.tupled(_ * _)}.sum
}
}
 
object Main extends App {
implicit def toDot[T: Numeric](v1: Seq[T]) = new Dot(v1)
 
val v1 = List(1, 3, -5)
val v2 = List(4, -2, -1)
println(v1 dot v2)
}

[edit] Seed7

$ include "seed7_05.s7i";
 
$ syntax expr: .().dot.() is -> 6; # priority of dot operator
 
const func integer: (in array integer: a) dot (in array integer: b) is func
result
var integer: sum is 0;
local
var integer: index is 0;
begin
if length(a) <> length(b) then
raise RANGE_ERROR;
else
for index range 1 to length(a) do
sum +:= a[index] * b[index];
end for;
end if;
end func;
 
const proc: main is func
begin
writeln([](1, 3, -5) dot [](4, -2, -1));
end func;

[edit] Scheme

Works with: Scheme version R5RS
(define (dot-product a b)
(apply + (map * a b)))
 
(display (dot-product '(1 3 -5) '(4 -2 -1)))
(newline)
Output:
3

[edit] Scilab

A = [1 3 -5]
B = [4 -2 -1]
C = sum(A.*B)

[edit] Slate

v@(Vector traits) <dot> w@(Vector traits)
"Dot-product."
[
(0 below: (v size min: w size)) inject: 0 into:
[| :sum :index | sum + ((v at: index) * (w at: index))]
].

[edit] Smalltalk

Works with: GNU Smalltalk
Array extend
[
* anotherArray [
|acc| acc := 0.
self with: anotherArray collect: [ :a :b |
acc := acc + ( a * b )
].
^acc
]
]
 
( #(1 3 -5) * #(4 -2 -1 ) ) printNl.

[edit] SNOBOL4

        define("dotp(a,b)sum,i")        :(dotp_end)
dotp i = 1; sum = 0
loop sum = sum + (a<i> * b<i>)
i = i + 1 ?a<i> :s(loop)
dotp = sum  :(return)
dotp_end
 
a = array(3); a<1> = 1; a<2> = 3; a<3> = -5;
b = array(3); b<1> = 4; b<2> = -2; b<3> = -1;
output = dotp(a,b)
end

[edit] SPARK

Works with SPARK GPL 2010 and GPS GPL 2010.

By defining numeric subtypes with suitable ranges we can prove statically that there will be no run-time errors. (The Simplifier leaves 2 VCs unproven, but these are clearly provable by inspection.)

The precondition enforces equality of the ranges of the two vectors.

with Spark_IO;
--# inherit Spark_IO;
--# main_program;
procedure Dot_Product_Main
--# global in out Spark_IO.Outputs;
--# derives Spark_IO.Outputs from *;
is
Limit : constant := 1000;
type V_Elem is range -Limit .. Limit;
V_Size : constant := 100;
type V_Index is range 1 .. V_Size;
type Vector is array(V_Index range <>) of V_Elem;
 
type V_Prod is range -(Limit**2)*V_Size .. (Limit**2)*V_Size;
--# assert V_Prod'Base is Integer;
 
subtype Index3 is V_Index range 1 .. 3;
subtype Vector3 is Vector(Index3);
Vect1 : constant Vector3 := Vector3'(1, 3, -5);
Vect2 : constant Vector3 := Vector3'(4, -2, -1);
 
function Dot_Product(V1, V2 : Vector) return V_Prod
--# pre V1'First = V2'First
--# and V1'Last = V2'Last;
is
Sum : V_Prod := 0;
begin
for I in V_Index range V1'Range
--# assert Sum in -(Limit**2)*V_Prod(I-1) .. (Limit**2)*V_Prod(I-1);
loop
Sum := Sum + V_Prod(V1(I)) * V_Prod(V2(I));
end loop;
return Sum;
end Dot_Product;
 
begin
Spark_IO.Put_Integer(File => Spark_IO.Standard_Output,
Item => Integer(Dot_Product(Vect1, Vect2)),
Width => 6,
Base => 10);
end Dot_Product_Main;
Output:
     3

[edit] SQL

ANSI sql does not support functions and is missing some other concepts that would be needed for a general case implementation of inner product (column names and tables would need to be first class in SQL -- capable of being passed to functions).

However, inner product is fairly simple to specify in SQL.

Given two tables A and B where A has key columns i and j and B has key columns j and k and both have value columns N, the inner product of A and B would be:

SELECT i, k, SUM(A.N*B.N) AS N
FROM A INNER JOIN B ON A.j=B.j
GROUP BY i, k

[edit] Standard ML

With lists:

val dot = ListPair.foldlEq Real.*+ 0.0
 
(*
- dot ([1.0, 3.0, ~5.0], [4.0, ~2.0, ~1.0]);
val it = 3.0 : real
*)

With vectors:

fun dot (v, u) = (
if Vector.length v <> Vector.length u then
raise ListPair.UnequalLengths
else ();
Vector.foldli (fn (i, v_i, z) => v_i * Vector.sub (u, i) + z) 0.0 v
)
 
(*
- dot (#[1.0, 3.0, ~5.0], #[4.0, ~2.0, ~1.0]);
val it = 3.0 : real
*)

[edit] Swift

func dot(v1: [Double], v2: [Double]) -> Double {
return reduce(lazy(Zip2(v1, v2)).map(*), 0, +)
}
 
println(dot([1, 3, -5], [4, -2, -1]))
Output:
3.0

[edit] Tcl

Library: Tcllib (Package: math::linearalgebra)
package require math::linearalgebra 
 
set a {1 3 -5}
set b {4 -2 -1}
set dotp [::math::linearalgebra::dotproduct $a $b]
proc pp vec {return \[[join $vec ,]\]}
puts "[pp $a] \u2219 [pp $b] = $dotp"
Output:
[1,3,-5] ∙ [4,-2,-1] = 3.0

[edit] TI-89 BASIC

dotP([1, 3, –5], [4, –2, –1])
    3

[edit] Ursala

A standard library function for dot products of floating point numbers exists, but a new one can be defined for integers as shown using the map operator (*) with the zip suffix (p) to construct a "zipwith" operator (*p), which operates on the integer product function. A catchable exception is thrown if the list lengths are unequal. This function is then composed (+) with a cumulative summation function, which is constructed from the binary sum function, and the reduction operator (:-) with 0 specified for the vacuous sum.

#import int
 
dot = sum:-0+ product*p
 
#cast %z
 
test = dot(<1,3,-5>,<4,-2,-1>)
Output:
3

[edit] Wart

def (dot_product x y)
(sum+map (*) x y)

+ is punned (overloaded) here; when applied to functions it denotes composition. Also, (*) is used to skip infix expansion.

Output:
(dot_product '(1 3 -5) '(4 -2 -1))

=> 3

[edit] XPL0

include c:\cxpl\codes;
 
func DotProd(U, V, L);
int U, V, L;
int S, I;
[S:= 0;
for I:= 0 to L-1 do S:= S + U(I)*V(I);
return S;
];
 
[IntOut(0, DotProd([1, 3, -5], [4, -2, -1], 3));
CrLf(0);
]
Output:
3

[edit] zkl

fcn dotp(a,b){Utils.zipWith('*,a,b).sum()}

zipWith stops at the shortest of the lists

Output:
dotp(T(1,3,-5),T(4,-2,-1,666)) //-->3

If exact length is a requirement

fcn dotp2(a,b){if(a.len()!=b.len())throw(Exception.ValueError);
Utils.zipWith('*,a,b).sum()
}
Personal tools
Namespaces

Variants
Actions
Community
Explore
Misc
Toolbox