Dot product: Difference between revisions

From Rosetta Code
Content added Content deleted
(Forth added)
(R version of dot product)
Line 167: Line 167:
a, b = [1, 3, -5], [4, -2, -1]
a, b = [1, 3, -5], [4, -2, -1]
assert dotp(a,b) == 3</lang>
assert dotp(a,b) == 3</lang>

=={{header|R}}==

Here are several ways to do the task.

<lang R>
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)
</lang>

=={{header|Scheme}}==
=={{header|Scheme}}==
{{Works with|Scheme|R<math>^5</math>RS}}
{{Works with|Scheme|R<math>^5</math>RS}}

Revision as of 12:58, 1 March 2010

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.

C

<lang c>#include <stdio.h>

  1. 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;

}</lang> Output: <lang>3</lang>

Clojure

Works with: Clojure version 1.1

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

<lang clojure>(defn dot-product [c1 c2]

 {:pre [(== (count c1) (count c2))]}
 (reduce + (map * c1 c2))
 )

(println (dot-product [1 3 -5] [4 -2 -1]))</lang>

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.

<lang factor>USING: kernel math.vectors sequences ;

dot-product ( u v -- w )
   2dup [ length ] bi@ =
   [ v. ] [ "Vector lengths must be equal" throw ] if ;</lang>
( scratchpad ) { 1 3 -5 } { 4 -2 -1 } dot-product .
3

Forth

<lang 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</lang>

Fortran

Works with: Fortran version 90 and later

<lang fortran>program test_dot_product

 write (*, '(i0)') dot_product ((/1, 3, -5/), (/4, -2, -1/))

end program test_dot_product</lang> Output: <lang>3</lang>

Haskell

<lang 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</lang>

J

<lang j> 1 3 _5 +/ . * 4 _2 _1 3

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

3</lang> The conjunction . applies generally to matricies and arrays of higher dimensions and can be used with verbs (functions) other than sum ( +/ ) and product ( * ).

<lang logo>to dotprod :a :b

 output apply "sum (map "product :a :b)

end

show dotprod [1 3 -5] [4 -2 -1]  ; 3</lang>

Lua

<lang 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}))</lang>

Oz

Vectors are represented as lists in this example. <lang oz>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]}}</lang>

Perl

<lang 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</lang>

PL/I

<lang 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; </lang>

Python

<lang 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</lang>

R

Here are several ways to do the task.

<lang R> x <- c(1, 3, -5) y <- c(4, -2, -1)

sum(x*y) # compute products, then do the sum x %*% y # inner product

  1. 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) </lang>

Scheme

Works with: Scheme version RRS

<lang scheme>(define (dot-product a b)

 (apply + (map * a b)))

(display (dot-product (list 1 3 -5) (list 4 -2 -1))) (newline)</lang> Output: <lang>3</lang>

SNOBOL4

<lang snobol4> define("dotp(a,b)sum,i")  :(dotp_end) dotp i = 1; sum = 0 loop sum = sum + (a * b)

       i = i + 1 ?a :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</lang>

Tcl

Library: tcllib

<lang tcl>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"</lang> Output:

[1,3,-5] ∙ [4,-2,-1] = 3.0

TI-89 BASIC

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