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
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>
Logo
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
uses struct::list from
<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::+
}
- 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