| 1 |
""" |
|---|
| 2 |
Matrix Solver |
|---|
| 3 |
Parses a calibration table and solves the equations for the alpha constants |
|---|
| 4 |
used in the Hardy's Multi-Quadric method of calibration. |
|---|
| 5 |
""" |
|---|
| 6 |
import os, sys, string |
|---|
| 7 |
from math import sqrt |
|---|
| 8 |
from xml.dom import * |
|---|
| 9 |
from xml.dom.minidom import * |
|---|
| 10 |
import Numeric, LinearAlgebra |
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
def length(v): |
|---|
| 14 |
""" |
|---|
| 15 |
Determines the magnitude of a three dimensional vector, v. |
|---|
| 16 |
""" |
|---|
| 17 |
return sqrt( v[0] * v[0] + v[1] * v[1] + v[2] * v[2] ) |
|---|
| 18 |
|
|---|
| 19 |
def vec_subtract(a, b): |
|---|
| 20 |
""" |
|---|
| 21 |
Returns a tuple c, s.t. c = a - b |
|---|
| 22 |
""" |
|---|
| 23 |
return (a[0] - b[0], a[1] - b[1], a[2] - b[2]) |
|---|
| 24 |
|
|---|
| 25 |
def vec_multiply(a, b): |
|---|
| 26 |
""" |
|---|
| 27 |
Returns the scalar result of a dot b. |
|---|
| 28 |
""" |
|---|
| 29 |
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] |
|---|
| 30 |
|
|---|
| 31 |
argc = len(sys.argv) |
|---|
| 32 |
if argc < 2 or argc > 3: |
|---|
| 33 |
print "Usage: matrix_solver.py input_file [output_file]" |
|---|
| 34 |
sys.exit(1) |
|---|
| 35 |
|
|---|
| 36 |
|
|---|
| 37 |
dbg_file = file('debug_output.txt', 'w') |
|---|
| 38 |
|
|---|
| 39 |
in_file = file(sys.argv[1], 'r') |
|---|
| 40 |
doc = parse(in_file) |
|---|
| 41 |
root_element = doc.documentElement |
|---|
| 42 |
|
|---|
| 43 |
offset_elements = root_element.getElementsByTagName('Offset') |
|---|
| 44 |
offset_table = {} |
|---|
| 45 |
|
|---|
| 46 |
|
|---|
| 47 |
keys_in_order = [] |
|---|
| 48 |
dbg_file.write('Parsed Offsets\n') |
|---|
| 49 |
|
|---|
| 50 |
for e in offset_elements: |
|---|
| 51 |
curr_offset = string.split(e.firstChild.data) |
|---|
| 52 |
qx = e.attributes['X'].nodeValue |
|---|
| 53 |
qy = e.attributes['Y'].nodeValue |
|---|
| 54 |
qz = e.attributes['Z'].nodeValue |
|---|
| 55 |
q = ( float(qx), float(qy), float(qz) ) |
|---|
| 56 |
px = curr_offset[0] |
|---|
| 57 |
py = curr_offset[1] |
|---|
| 58 |
pz = curr_offset[2] |
|---|
| 59 |
p = ( float(px), float(py), float(pz) ) |
|---|
| 60 |
dbg_file.write('(' + qx + ',' + qy + ',' + qz + '):(' + px + ',' + py + ',' + pz + ')\n') |
|---|
| 61 |
dbg_file.write(str(q) + ' : ' + str(p) + '\n') |
|---|
| 62 |
offset_table[q] = p |
|---|
| 63 |
keys_in_order.append(q) |
|---|
| 64 |
dbg_file.write('\nOffset Table\n') |
|---|
| 65 |
dbg_file.write(str(offset_table)) |
|---|
| 66 |
|
|---|
| 67 |
|
|---|
| 68 |
w_matrix_list = [] |
|---|
| 69 |
r_squared = 0.4 |
|---|
| 70 |
print 'Calculating W Matrix...' |
|---|
| 71 |
for i in range(0, len(offset_table)): |
|---|
| 72 |
w_matrix_row = [] |
|---|
| 73 |
p = offset_table[keys_in_order[i]] |
|---|
| 74 |
for j in range(0, len(offset_table)): |
|---|
| 75 |
pj = offset_table[keys_in_order[j]] |
|---|
| 76 |
p_difference = vec_subtract(p, pj) |
|---|
| 77 |
w = sqrt(vec_multiply(p_difference, p_difference) + r_squared) |
|---|
| 78 |
w_matrix_row.append(w) |
|---|
| 79 |
w_matrix_list.append(w_matrix_row) |
|---|
| 80 |
dbg_file.write('\nW Matrix List\n') |
|---|
| 81 |
dbg_file.write( str(w_matrix_list) ) |
|---|
| 82 |
w_matrix = Numeric.array(w_matrix_list) |
|---|
| 83 |
dbg_file.write('\nW Matrix\n') |
|---|
| 84 |
dbg_file.write( str(w_matrix) ) |
|---|
| 85 |
q_list = [] |
|---|
| 86 |
|
|---|
| 87 |
|
|---|
| 88 |
for k in keys_in_order: |
|---|
| 89 |
q_list.append( list(k) ) |
|---|
| 90 |
dbg_file.write('\nQ List\n') |
|---|
| 91 |
dbg_file.write( str(q_list) ) |
|---|
| 92 |
q_vector = Numeric.array(q_list) |
|---|
| 93 |
print 'Solving for alpha vector...' |
|---|
| 94 |
alpha_vector = LinearAlgebra.solve_linear_equations(w_matrix, q_vector) |
|---|
| 95 |
dbg_file.write('\nAlpha Vector\n') |
|---|
| 96 |
dbg_file.write( str(alpha_vector) ) |
|---|
| 97 |
print 'Alpha Vector found.' |
|---|
| 98 |
out_file = '' |
|---|
| 99 |
if argc == '2': |
|---|
| 100 |
out_file = sys.argv[1] |
|---|
| 101 |
else: |
|---|
| 102 |
out_file = sys.argv[2] |
|---|
| 103 |
in_file.close() |
|---|
| 104 |
out_file = file(out_file, 'w') |
|---|
| 105 |
alpha_vector_list = alpha_vector.tolist() |
|---|
| 106 |
dbg_file.write('\nCheck Solution\n') |
|---|
| 107 |
solution_check = Numeric.matrixmultiply(w_matrix, alpha_vector) |
|---|
| 108 |
dbg_file.write( str(solution_check) ) |
|---|
| 109 |
|
|---|
| 110 |
|
|---|
| 111 |
for i in alpha_vector_list: |
|---|
| 112 |
element = Element('Alpha') |
|---|
| 113 |
element.setAttribute('X', str(i[0])) |
|---|
| 114 |
element.setAttribute('Y', str(i[1])) |
|---|
| 115 |
element.setAttribute('Z', str(i[2])) |
|---|
| 116 |
root_element.appendChild(element) |
|---|
| 117 |
out_file.write(doc.toprettyxml()) |
|---|
| 118 |
out_file.close() |
|---|