#!/usr/bin/perl
#
# Compute length a spring will stretch
#
# MWR 2/20/2021

$debug = 1;
srand();

# force constant (N/m)
$k = 2.5;
# rest length of spring (cm)
$rest_length = 8.2;
# accel due to grav (m/s^2)
$g = 9.80;

# masses to be hung from spring (grams)
@mass_array = (20.0, 30.0, 40.0, 60.0, 80.0, 100.0, 120.0);
# uncertainty in measurement (cm)
$uncert_amplitude = 1.5;

$num = $#mass_array;
for ($i = 0; $i <= $num; $i++) {

  $mass = $mass_array[$i];
  $uncert = $uncert_array[$i];
  
  $mass_kg = $mass*0.001;
  $force_newton = $mass_kg*$g;
  $delta_x_m = ($force_newton / $k);
  $delta_x_cm = $delta_x_m*100.0;

  $length_cm = $rest_length + $delta_x_cm;
  $measured_length = $length_cm + $uncert_amplitude*gaussian_rand();

  printf " mass %5.0f grams  length %5.1f \n", $mass, $measured_length;



}

exit 0;






######################################################################
# PROCEDURE: gaussian_rand
#
# DESCRIPTION: Returns a random number drawn from a gaussian (normal)
#              distribution with mean 0.0 and standard deviation 1.0.
#
#              Stolen from 
#
#                 http://www.unix.com.ua/orelly/perl/cookbook/ch02_11.htm
#
#
sub gaussian_rand {
    my ($u1, $u2);  # uniformly distributed random numbers
    my $w;          # variance, then a weight
    my ($g1, $g2);  # gaussian-distributed numbers

    do {
        $u1 = 2 * rand() - 1;
        $u2 = 2 * rand() - 1;
        $w = $u1*$u1 + $u2*$u2;
    } while ( $w >= 1 );

    $w = sqrt( (-2 * log($w))  / $w );
    $g2 = $u1 * $w;
    $g1 = $u2 * $w;
    # could return both if wanted
    #   return wantarray ? ($g1, $g2) : $g1;
    # but I need just one
    return($g1);
}






