File: linfit.t

package info (click to toggle)
pdl 1%3A2.4.7%2Bdfsg-2
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 10,128 kB
  • ctags: 5,821
  • sloc: perl: 26,328; fortran: 13,113; ansic: 9,378; makefile: 71; sh: 50; sed: 6
file content (129 lines) | stat: -rw-r--r-- 2,747 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use PDL::LiteF;
BEGIN {
        eval " use PDL::Fit::Linfit; ";
        $loaded = ($@ ? 0 : 1);
}

kill INT,$$ if $ENV{UNDER_DEBUGGER}; # Useful for debugging.
print "1..2\n";

unless ($loaded) {
        for (1..2) {
                print "ok $_ # Skipped: probably PDL::Slatec not available.\n";
        }
        exit;
}


my $testNo = 1;


# Simple Test Case:

# Generate data from a set of functions
my $xvalues = sequence(100);
$data = 3*$xvalues + 2*cos($xvalues) + 3*sin($xvalues*2); 

# Fit functions are the linear, cos, and sin2x functions used in
#   the data generation step above:
$fitFuncs = cat $xvalues, cos($xvalues), sin($xvalues*2);

# Perform the fit, Coefs should equal 3,2,3
my ($yfit, $coeffs) = PDL::linfit1d($data,$fitFuncs);

my @coefs = $coeffs->list;

ok( $testNo++, tapprox( $coefs[0], 3) && tapprox( $coefs[1], 2) && tapprox( $coefs[2], 3) );


# More Complex Example
	

my $noPoints = 501;

my @expectedCoefs = qw( 0.988375918186647 -0.000278823311771375 0.161669997297754 0.0626069008452451);

my $noCoefs = 4;
my $i;
my  ($deltaT,$Amp,$lin,$HOper,$AmpHO,$Amphalf,$Ampfull);

my @PulsedB;

my  @Pulse;
my  $psum = 0;

my  $pi = 3.1415926;

my  $Pwidth = 2000;
my $pave;

$deltaT = 4;  # 4 nS increments
$Amp = 2.8;   # 2.8V amplitude of pulse
$lin = .2;
$HOper = 200;  # HO period
$AmpHO=.1;
$Amphalf = .5;
$Ampfull = .2;

# generate waveform:
for($i=0;$i<$noPoints;$i++){
	$PulsedB[$i]=
		-$lin*1e-3*$i*$deltaT + 
		$Amphalf*sin($pi/$Pwidth*$i*$deltaT)  +
		$Ampfull*sin(2*$pi/$Pwidth*$i*$deltaT) +
		$AmpHO*sin(2*$pi/$HOper*$i*$deltaT);

	$Pulse[$i] = $Amp*exp($PulsedB[$i]/20*2.3025851);
	$psum += $Pulse[$i];  # used to get DC value

	# printf(" %4d  %g  %g\n",$i,$PulsedB[$i],$Pulse[$i]);

}

$pave = $psum/$noPoints;

# printf("DC Value = %g\n",$pave);


# Make PDL from waveform:
my $data = new PDL( \@Pulse);


# setup matrix contains functions to fit
for ($i=0; $i<$noPoints; $i++) {

$functions[0][$i] = $pave;
$functions[1][$i] = $i;
$functions[2][$i] = sin($pi*$i/($noPoints-1));
$functions[3][$i] = sin(2*$pi*$i/($noPoints-1));

}

my $fitFuncs = new PDL( \@functions);

($yfit, $coeffs) = linfit1d( $data, $fitFuncs);

@coefs = $coeffs->list;

ok( $testNo++, tapprox( $coefs[0], $expectedCoefs[0]) && 
		tapprox( $coefs[1], $expectedCoefs[1]) &&
		tapprox( $coefs[2], $expectedCoefs[2]) &&
		tapprox( $coefs[3], $expectedCoefs[3]) 
	 );


sub tapprox {
        my($a,$b) = @_;
        my $c = abs($a-$b);
        my $d = ref($c) ? $c->{PDL}->max : $c ;  # don't do a make if were are dealing 
					  # with a scalar
        $d < 0.00001;
}
#  Testing utility functions:
sub ok {
        my $no = shift ;
        my $result = shift ;
        print "not " unless $result ;
        print "ok $no\n" ;
}