Sum of a series

From Rosetta Code
Revision as of 03:20, 5 June 2009 by rosettacode>Timmyd (added slate language)
Task
Sum of a series
You are encouraged to solve this task according to the task description, using any language you may know.

Display the sum of a finite series for a given range.

For this task, use S(x) = 1/x2, from 1 to 1000. (This approximates the Riemann zeta function. The Basel problem solved this: ζ(2) = p2/6.)

Ada

<lang ada>with Ada.Text_Io; use Ada.Text_Io;

procedure Sum_Series is

  function F(X : Long_Float) return Long_Float is
  begin
     return 1.0 / X**2;
  end F;
  package Lf_Io is new Ada.Text_Io.Float_Io(Long_Float);
  use Lf_Io;
  Sum : Long_Float := 0.0;
  subtype Param_Range is Integer range 1..1000;

begin

  for I in Param_Range loop
     Sum := Sum + F(Long_Float(I));
  end loop;
  Put("Sum of F(x) from" & Integer'Image(Param_Range'First) &
     " to" & Integer'Image(Param_Range'Last) & " is ");
  Put(Item => Sum, Aft => 10, Exp => 0);
  New_Line;

end Sum_Series;</lang>

ALGOL 68

Works with: ALGOL 68 version Standard - no extensions to language used
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 RANGE = STRUCT(INT lwb, upb);

PROC sum = (PROC (INT)LONG REAL f, RANGE range)LONG REAL:(
  LONG REAL sum := LENG 0.0;
  FOR i FROM lwb OF range TO upb OF range DO
     sum := sum + f(i)
  OD;
  sum
);

RANGE range = (1,100);
PROC f = (INT x)LONG REAL: LENG REAL(1) / LENG REAL(x)**2;

print(("Sum of f(x) from", lwb OF range, " to ",upb OF range," is ", SHORTEN sum(f,range),".", new line))

Output:

Sum of f(x) from         +1 to        +100 is +1.63498390018489e  +0.

AutoHotkey

AutoHotkey allows the precision of floating point numbers generated by math operations to be adjusted via the SetFormat command. The default is 6 decimal places. <lang autohotkey>SetFormat, FloatFast, 0.15 While A_Index <= 1000

sum += 1/A_Index**2

MsgBox,% sum ;1.643934566681554</lang>

AWK

<lang awk>$ awk 'BEGIN{for(i=1;i<=1000;i++)s+=1/(i*i);print s}' 1.64393</lang>

C

<lang c>#include <stdio.h>

double Invsqr(double n) { return 1 / (n*n); }

int main (int argc, char *argv[]) { int i, start = 1, end = 1000; double sum = 0.0;

for( i = start; i <= end; i++) sum += Invsqr((double)i);

printf("%16.14f\n", sum);

return 0; } </lang>

C++

<lang cpp>#include <iostream>

double f(double x);

int main() {

       unsigned int start = 1;
       unsigned int end = 1000;
       double sum = 0;
       double sum = 0;
       for(    unsigned int x = start;
                       x <= end;
                       ++x                     )
       {
               sum += f(x);
       }
       }
       std::cout << "Sum of f(x) from " << start << " to " << end << " is " << sum << std::endl;
       return 0;

}


double f(double x) {

       return ( 1 / ( x * x ) );

} </lang>

Common Lisp

<lang lisp>(loop for x from 1 to 1000 summing (/ (expt x 2)))</lang>

D

<lang d> import std.stdio, std.traits;

ReturnType!(TF) series(TF)(TF func, int end, int start=1) {

   ReturnType!(TF) sum = 0;
   for (int i = start; i <= end; i++)
       sum += func(i);
   return sum;

}

void main() {

   writefln("Sum: ", series((int n){return 1.0L / (n*n);}, 1_000));

} </lang>

E

pragma.enable("accumulator")
accum 0 for x in 1..1000 { _ + 1 / x ** 2 }

Forth

: sum ( fn start count -- fsum )
  0e
  bounds do
    i s>d d>f dup execute f+
  loop drop ;

:noname ( x -- 1/x^2 ) fdup f* 1/f ;   ( xt )
1 1000 sum f.       \ 1.64393456668156
pi pi f* 6e f/ f.   \ 1.64493406684823

Fortran

In ISO Fortran 90 and later, use SUM intrinsic:

 real, dimension(1000) :: a = (/ (1.0/(i*i), i=1, 1000) /)
 real :: result
 
 result = sum(a);

F#

The following function will do the task specified.

let rec f (x : float) = 
    match x with
        | 0. -> x
        | x -> (1. / (x * x)) + f (x - 1.)

In the interactive F# console, using the above gives:

> f 1000. ;;
val it : float = 1.643934567

However this is not a tail recursive function and will run out of stack space eventually (try 100000). A tail recursive implementation will not consume stack space and can therefore handle much larger ranges.

#light
let sum_series (max : float) =
    let rec f (a:float, x : float) = 
        match x with
            | 0. -> a
            | x -> f ((1. / (x * x) + a), x - 1.)
    f (0., max)

[<EntryPoint>]
let main args =
    let (b, max) = System.Double.TryParse(args.[0])
    printfn "%A" (sum_series max)
    0

This block can be compiled using fsc --target exe filename.fs or used interactively without the main function.

Groovy

Start with smallest terms first to minimize rounding error: <lang groovy>println ((1000..1).collect { x -> 1/(x*x) }.sum())</lang>

Output:

1.6439345654

Haskell

With a list comprehension:

sum [1 / x ^ 2 | x <- [1..1000]]

With higher-order functions:

sum $ map (\x -> 1 / x ^ 2) [1..1000]

In point-free style:

(sum . map (1/) . map (^2)) [1..1000]

Icon

procedure main()
   local i, sum
   sum := 0 & i := 0
   every sum +:= 1.0/((| i +:= 1 ) ^ 2) \1000
   write(sum)
end

IDL

 print,total( 1/(1+findgen(1000))^2)

J

   NB. sum of inverse of square of first thousand positive integers
   +/ % *: >: i. 1000
1.64393
   
   (*:o.1)%6       NB. pi squared over six, for comparison
1.64493
  
   1r6p2           NB.  As a constant (J has a rich constant notation)

1.64493

Java

<lang java>public class Sum{

   public static double f(double x){
      return 1/(x*x);
   }

   public static void main(String[] args){
      double start = 1;
      double end = 1000;
      double sum = 0;

      for(double x = start;x <= end;x++) sum += f(x);

      System.out.println("Sum of f(x) from " + start + " to " + end +" is " + sum);
   }

}</lang>

JavaScript

<lang javascript>function sum(a,b,fn) {

  var s = 0;
  for ( ; a <= b; a++) s += fn(a);
  return s;

}

sum(1,1000, function(x) { return 1/(x*x) } )  // 1.64393456668156</lang>

to series :fn :a :b
  localmake "sigma 0
  for [i :a :b] [make "sigma :sigma + invoke :fn :i]
  output :sigma
end
to zeta.2 :x
  output 1 / (:x * :x)
end
print series "zeta.2 1 1000
make "pi (radarctan 0 1) * 2
print :pi * :pi / 6

Lucid

series = ssum asa  n >= 1000
   where
         num = 1 fby num + 1;
         ssum = ssum + 1/(num * num)
   end;

Mathematica

This is the straightforward solution of the task:

Sum[1/x^2, {x, 1, 1000}]

However this returns a quotient of two huge integers (namely the exact sum); to get a floating point approximation, use N:

N[Sum[1/x^2, {x, 1, 1000}]]

Alternatively, get Mathematica to do the whole calculation in floating point by using a floating point value in the formula:

Sum[1./x^2, {x, 1, 1000}]

MAXScript

total = 0
for i in 1 to 1000 do
(
    total += 1.0 / pow i 2
)
print total

Nial

|sum (1 / power (count 1000) 2)
=1.64393

OCaml

<lang ocaml>let sum a b fn =

 let result = ref 0. in
 for i = a to b do
   result := !result +. fn i
 done;
 !result</lang>
# sum 1 1000 (fun x -> 1. /. (float x ** 2.))
- : float = 1.64393456668156124

Octave

Given a vector, the sum of all its elements is simply sum(vector); a range can be generated through the range notation: sum(1:1000) computes the sum of all numbers from 1 to 1000. To compute the requested series, we can simply write:

<lang octave>sum(1 ./ [1:1000] .^ 2)</lang>


OpenEdge/Progress

Conventionally like elsewhere:

def var dcResult as decimal no-undo.
def var n as int no-undo.

do n = 1 to 1000 :
  dcResult = dcResult + 1 / (n * n)  .
end.

display dcResult .

or like this:

def var n as int no-undo.

repeat n = 1 to 1000 :
  accumulate 1 / (n * n) (total).
end.

display ( accum total 1 / (n * n) )  .


Perl

<lang perl>my $sum = 0; $sum += 1 / $_ ** 2 foreach 1..1000; print "$sum\n";</lang> or <lang perl>use List::Util qw(reduce); $sum = reduce { $a + 1 / $b ** 2 } 0, 1..1000; print "$sum\n";</lang>

Pop11

lvars s = 0, j;
for j from 1 to 1000 do
    s + 1.0/(j*j) -> s;
endfor;

s =>

Python

<lang python>print sum(1.0 / x ** 2 for x in range(1, 1001))</lang>

R

print( sum( 1/seq(1000)^2 ) )

Ruby

<lang ruby>puts (1..1000).inject(0) {|sum, x| sum + 1.0 / x ** 2}</lang>

Scheme

<lang scheme>(define (sum a b fn)

 (do ((i a (+ i 1))
      (result 0 (+ result (fn i))))
     ((> i b) result)))

(sum 1 1000 (lambda (x) (/ 1 (* x x)))) ; fraction (exact->inexact (sum 1 1000 (lambda (x) (/ 1 (* x x))))) ; decimal</lang>

Slate

Manually coerce it to a float, otherwise you will get an exact (and slow) answer:

<lang slate> ((1 to: 1000) reduce: [|:x :y | ((y * y) reciprocal as: Float) + x]). </lang>

Smalltalk

<lang smalltalk>( (1 to: 1000) fold: [:sum :aNumber |

 sum + (aNumber squared reciprocal) ] ) asFloat displayNl.</lang>

Tcl

Works with: Tcl version 8.5

uses struct::list from

Library: tcllib

<lang tcl>package require Tcl 8.5 package require struct::list

proc sum_of {lambda nums} {

   struct::list fold [struct::list map $nums [list apply $lambda]] 0 ::tcl::mathop::+

}

  1. a range command akin to Python's

proc range args {

   foreach {start stop step} [switch -exact -- [llength $args] {
       1 {concat 0 $args 1}
       2 {concat   $args 1}
       3 {concat   $args  }
       default {error {wrong # of args: should be "range ?start? stop ?step?"}}
   }] break
   if {$step == 0} {error "cannot create a range when step == 0"}
   set range [list]
   while {$step > 0 ? $start < $stop : $stop < $start} {
       lappend range $start
       incr start $step
   }
   return $range

}

set S {x {expr {1.0 / $x**2}}}

set sum [sum_of $S [range 1 1001]] ;# ==> 1.6439345666815615</lang>

UnixPipes

term() {
   b=$1;res=$2
   echo "scale=5;1/($res*$res)+$b" | bc
}
sum() {
  (read B; res=$1;
  test -n "$B" && (term $B $res) || (term 0 $res))
}
fold() {
  func=$1
  (while read a ; do
      fold $func | $func $a
  done)
}
(echo 3; echo 1; echo 4) | fold sum