libloopfit.pl
author A.M. Thurnherr <athurnherr@yahoo.com>
Sat, 24 Jul 2021 09:38:16 -0400
changeset 46 70e566505a12
parent 17 4b7486d77b39
permissions -rw-r--r--
V7.3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
17
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     1
#======================================================================
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     2
#                    L I B L O O P F I T . P L 
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     3
#                    doc: Thu Mar 12 08:05:26 2015
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     4
#                    dlm: Sun Mar 15 19:46:49 2015
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     5
#                    (c) 2015 A.M. Thurnherr
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     6
#                    uE-Info: 47 22 NIL 0 0 72 2 2 4 NIL ofnI
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     7
#======================================================================
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     8
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     9
# HISTORY:
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    10
#	Mar 12, 2015: - created
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    11
#	Mar 15, 2015: - added [libQZ.pl]
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    12
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    13
require "$ANTS/nrutil.pl";
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    14
require "$ANTS/libSVD.pl";										# for circular fit
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    15
require "$ANTS/libQZ.pl";										# for ellipse fit
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    16
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    17
#----------------------------------------------------------------------
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    18
# fitCircle(\@x,\@y) => ($r,$cx,$cy)
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    19
#	\@x,\@y		references to list of data values
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    20
#	$r			circle radius
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    21
#	$cx,$cy		circle center
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    22
#----------------------------------------------------------------------
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    23
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    24
sub fitCircle($$)
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    25
{
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    26
	my($xR,$yR) = @_;
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    27
	my(@A,@V,@W);
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    28
	my($nSamp) = scalar(@{$xR});
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    29
	my($nParam) = 3;
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    30
	
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    31
	matrix(\@A,1,$nSamp,1,$nParam); 							# rows, then columns
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    32
	matrix(\@V,1,$nParam,1,$nParam);							# 3x3 matrix for circle fitting
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    33
	vector(\@W,1,$nParam);										# diag matrix of singular values output as vector
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    34
	vector(\@b,1,$nSamp);										# rhs
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    35
	vector(\@coeff,1,$nParam);									# fit coefficients
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    36
	
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    37
	for ($r=1; $r<=$nSamp; $r++) {								# circle equation c1*x + c2*y + c3 = -(x^2 + y^2)
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    38
		$A[$r][1] = $xR->[$r-1];								#	r  = sqrt((c1^2 + c2^2)/4 - c3)
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    39
		$A[$r][2] = $yR->[$r-1];								#	cx = -c1/2
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    40
		$A[$r][3] = 1;											#	cy = -c2/2
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    41
		$b[$r] = -($xR->[$r-1]**2+$yR->[$r-1]**2);
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    42
	}
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    43
	
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    44
	svdcmp(\@A,\@W,\@V);										# solve Ax = b, with x == coeff
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    45
	svbksb(\@A,\@W,\@V,\@b,\@coeff);
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    46
	
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    47
	return ($coeff[1],$coeff[2],$coeff[3]);
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    48
	my($r)	= sqrt(($coeff[1]**2+$coeff[2]**2)/4-$coeff[3]);
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    49
	my($cx) = -0.5*$coeff[1];
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    50
	my($cy) = -0.5*$coeff[2];
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    51
	return ($r,$cx,$cy);
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    52
}
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    53
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    54
#----------------------------------------------------------------------
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    55
# fitEllipse(\@x,\@y) => ?
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    56
#	\@x,\@y		references to list of data values
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    57
#
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    58
#	Direct Least Square Fitting of Ellipses
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    59
#	Andrew Fitzgibbon, Maurizio Pilu, and Robert B. Fisher, MAY 1999
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    60
# 	IEEE transactions on pattern analysis and machine intelligence 21(5): 476-480
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    61
#----------------------------------------------------------------------
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    62
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    63
sub fitEllipse($$)
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    64
{
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    65
	my($xR,$yR) = @_;
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    66
	my($nSamp) = scalar(@{$xR});
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    67
	
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    68
	# design matrix D = [ x.*x x.*y y.*y x y ones(size(x)) ]; 
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    69
	my(@D);
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    70
	for (my($r)=0; $r<$nSamp; $r++) {
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    71
		$D[$r][0] = $xR->[$r]**2;
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    72
		$D[$r][1] = $xR->[$r] * $yR->[$r];
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    73
		$D[$r][2] = $yR->[$r]**2;
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    74
		$D[$r][3] = $xR->[$r];
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    75
		$D[$r][4] = $yR->[$r];
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    76
		$D[$r][5] = 1;
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    77
	}
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    78
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    79
	# scatter matrix S = D' * D;
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    80
	my(@S);
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    81
	for (my($i)=0; $i<6; $i++) {
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    82
		for (my($j)=0; $j<6; $j++) {
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    83
			for (my($k)=0; $k<$nSamp; $k++) {
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    84
				$S[$i][$j] += $D[$k][$j] * $D[$k][$i];
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    85
			}
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    86
		}
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    87
	}
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    88
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    89
	# 6x6 constraint matrix C
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    90
	my(@C);
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    91
	for (my($r)=0; $r<6; $r++) {
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    92
		for (my($c)=0; $c<6; $c++) {
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    93
			$C[$r][$c] = 0;
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    94
		}
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    95
	}
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    96
	$C[0][2] = -2; $C[1][1] = 1; $C[2][0] = -2;
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    97
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    98
	# solve generalized eigensystem
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    99
	my(@geRe,@geImg,@geVec);
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   100
	eig(\@S,\@C,\@geRe,\@geImg,\@geVec);
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   101
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   102
	# find only negative eigenvalue
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   103
	my($i);
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   104
	for ($i=0; $i<@geRe; $i++) {
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   105
		last if (numberp($geRe[$i]) && ($geRe[$i] < 0));
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   106
	}
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   107
	croak("internal error") unless ($geRe[$i] < 0);
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   108
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   109
	# get fitted parameters
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   110
	return @{$geVec[$i]};
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   111
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   112
}
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   113
4b7486d77b39 V6.0 release candidate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   114
1;