Code Documentation¶
Tensor Rank Visualization Tool
Copyright (c) 2009 Martin J. Mohlenkamp
Released under the terms of the GNU General Public License.
Portions contributed by student research assistants:
Sruthi Devarachetty
Rob Vanyo
Krishna Palavarapu
Nam Nguyen
Besides functions and classes, defines
colorlist: a global list of colors used, from dark to light
anglelist: a global list of angles at which to change color
Main Driver¶
- trvtool.start_trv_GUI()¶
Start the main Graphical User Interface
Classes¶
basic tensor class¶
- class trvtool.SumSeparableTensor(data=None)¶
Return a Sum of Separable Tensors.
- Parameters:
data – either None or a list/array object whose entries are conceptually added. Each entry is a list/array object whose entries are conceptually tensor producted. Each entry of those is a list/array. Thus the whole thing could be a 3D array.
Represents
\[\begin{split}T(i_1,i_2,\ldots,i_d)&=V^1_1(i_1)V^1_2(i_2)\cdots V^1_d(i_d)+ V^2_1(i_1)V^2_2(i_2)\cdots V^2_d(i_d)+\cdots +V^r_1(i_1)V^r_2(i_2)\cdots V^r_d(i_d)\\ &=\sum_{l=1}^r \prod_{k=1}^d V^l_k(i_k)\end{split}\]Note
Some portions assume input is a numpy.array.
- innerproduct(other)¶
Compute the innerproduct of the SumSeparableTensor with another.
In theory this is
\[\langle T, U \rangle = \sum_{i_1=1}^M\sum_{i_2=1}^M\cdots\sum_{i_d=1}^M T(i_1,i_2,\ldots,i_d)\bar{U}(i_1,i_2,\ldots,i_d)\]but it is actually computed by
\[\langle T, U \rangle =\sum_{l=1}^r \sum_{m=1}^s \prod_{k=1}^d \sum_{i=1}^MV^l_k(i)\bar{W}^m_k(i) =\sum_{l=1}^r \sum_{m=1}^s \prod_{k=1}^d \langle V^l_k, W^m_k \rangle\]- Parameters:
other (SumSeparableTensor) – the tensor to take inner product with
- Returns:
scalar value of inner product
Can handle real or complex
- normalize()¶
Divide by its norm in place; return norm
to hold the state of the visualization¶
- class trvtool.StateHolder(basepoints, plotrank=2, xytlist=None)¶
Holds the state of the visualization, for real tensors only.
Does not hold plotting parameters (zoom, orientation, etc.)
- Parameters:
basepoints (list) – the 3 SumSeparableTensor that define the plotting plane.
plotrank (int >0) – separation rank of points to plot
xytlist (list or None) – the plotting points already computed as (x,y,angle)
From the basepoints computes and stores the following things that are reused often:
dimension: physical dimension, meaning number of indices in the tensor.
resolution: discretization parameter in each direction
angle, ratio: as returned by findMainGeometry
cosmainangle,sinmainangle: cos and sin of angle
IPmatrix: the matrix of inner products between base points, produced by makeGrammMatrix.
invIPmatrix: the inverse of IPmatrix.
- static generate_state(dimension=3, resolution=3, plotrank=2, baserank=1)¶
Generate a state using random base Tensors.
- Parameters:
dimension –
- info(doprint=False, verbose=2)¶
Return a string with info about self.
- Parameters:
doprint (Boolean) – if True, also print the info
verbose –
how much to print
verbose ==0 is the basic parameters
verbose ==1 includes derived quantities
verbose ==2 includes all the points
- class trvtool.StateHolder_complex(basepoints, plotrank=2, xytlist=None)¶
Holds the state of the visualization, for complex tensors.
Does not hold plotting parameters (zoom, orientation, etc.)
- Parameters:
basepoints (list) – the 2 SumSeparableTensor that define the plotting complex line.
plotrank (int >0) – separation rank of points to plot
xytlist (list or None) – the plotting points already computed as (x,y,angle)
From the basepoints computes and stores the following things that are reused often:
dimension: physical dimension, meaning number of indices in the tensor.
resolution: discretization parameter in each direction
IPmatrix: the matrix of inner products between base points, produced by makeGrammMatrix.
invIPmatrix: the inverse of IPmatrix.
- info(doprint=False, verbose=2)¶
Return a string with info about self.
- Parameters:
doprint (Boolean) – if True, also print the info
verbose –
how much to print
verbose ==0 is the basic parameters
verbose ==1 includes derived quantities
verbose ==2 includes all the points
GUI windows and frames¶
- class trvtool.TrimFrame(parent, radius=0.01)¶
Class for cropping points outside of desired rectangle, or covered.
- Parameters:
parent – The frame that this one is inside.
radius – The radius to use to decide if one disc covers another; passed to the function trimcovered.
Has buttons:
‘Crop’ to crop to an input rectangle.
‘Trim Covered’ to remove covered points.
Updates parent.state when buttons are pushed.
- doTrim()¶
Trims points from list outside of a given rectangle
NOTE: This is a permanent deletion of points from the xytlist.
- doTrimCovered()¶
Trims points covered by other points
- class trvtool.LineFrame(parent)¶
Class for creating line of points.
- Parameters:
parent – The frame that this one is inside.
Has button ‘Line’ to create a line of points.
Updates parent.state when button is pushed.
- doLine()¶
Make a line of points
- class trvtool.ALSFrame(parent)¶
Class for creating grid of points using Alternating Least Squares.
- Parameters:
parent – The frame that this one is inside.
Has button ‘ALS’ to create a grid of points, trying to fit those on the plane.
Updates parent.state when button is pushed.
- doALS()¶
Make a grid of points with ALS.
Note
hardwired fitting parameters.
- class trvtool.PostScriptFrame(parent)¶
Class for the option to plot to a printable .eps file.
- Parameters:
parent – The frame that this one is inside.
Has button ‘Render to’ to render to file.
Writes to file when button is pushed.
- doPlotPS(confirm=False)¶
Actually write the EPS file.
- Parameters:
confirm (Boolean) – whether or not to display a confirmation window
- class trvtool.state_display_dialog(parent)¶
Dialog for seeing full state.
- Parameters:
parent – the window or frame that generated this one.
result is always None.
- body(master)¶
Set up display of text, show stateholder info.
- validate()¶
Validate the types of the entries.
- Returns:
1 , always
- class trvtool.trv_visual_gui(master, state)¶
Start the window for a visualization over the reals.
- Parameters:
master – the window or frame that generated this one.
state – The StateHolder with the visualization so far.
- saveFile()¶
Save a state to a file
- show_help()¶
Display Help
- show_state_info()¶
Display info on state
- update_plotrank()¶
Update the plot rank. If it decreases will clear xytlist.
- class trvtool.new_random_dialog(parent)¶
Dialog for inputing parameters for a new random state.
- Parameters:
parent – the window or frame that generated this one.
The result of the dialog is in self.result.
If the dialog was cancelled, result is None. Otherwise it is a tuple (dimension,resolutions,baserank,plotrank)
resolutions is a list of ints of length dimension, and the others are ints. There is some validation of these entries.
- body(master)¶
Set up the entry fields.
We have:
field (R or C)
dimension
baserank
plotrank
resolutions
- validate()¶
Validate the types of the entries.
- Returns:
1 if okay, 0 if not
- class trvtool.new_manual_dialog(parent)¶
Dialog for manually inputting base tensors for a new state, real only.
- Parameters:
parent – the window or frame that generated this one.
The result of the dialog is in self.result.
If the dialog was cancelled, result is None. Otherwise it is a tuple (basis,plotrank)
basis is a list of 3 SumSeparableTensor plotrank is an int
There is some validation of these entries.
- body(master)¶
Set up the entry fields.
We have:
plotrank
3 base tensors as list of list of list
- validate()¶
Validate the types of the entries.
- Returns:
1 if okay, 0 if not
- class trvtool.new_manual_dialog_complex(parent)¶
Dialog for manually inputting base tensors for a new state, complex.
- Parameters:
parent – the window or frame that generated this one.
The result of the dialog is in self.result.
If the dialog was cancelled, result is None. Otherwise it is a tuple (basis,plotrank)
basis is a list of 2 SumSeparableTensor plotrank is an int
There is some validation of these entries.
- body(master)¶
Set up the entry fields.
We have:
plotrank
2 base tensors as list of list of list
- validate()¶
Validate the types of the entries.
- Returns:
1 if okay, 0 if not
- class trvtool.trv_start_frame(parent=None)¶
Start the frame for the Tensor Rank Visualization tool.
Has:
‘Exit’ to exit
‘Load’ to load a saved visualization
‘New’ to start a new one, two versions
More than one visualization can be run from the same gui
- load_state()¶
Read a state from a file
- new_manual()¶
Start a new visualization, manually entering base tensors, over R
- new_manual_complex()¶
Start a new visualization, manually entering base tensors, over C
- new_random()¶
Start a new visualization, random basepoints
- visualize(state)¶
Open new window that knows the state and can visualize.
- Parameters:
state (StateHolder) – the data for the visualization
Functions¶
- trvtool.assigncolor(angle)¶
Assign a list to an angle that will be interpreted later in PostScript as a color using the RGB colorspace.
- Parabeter angle:
angle between the plane and a target point, in radians. The angle should be between 0 and pi/2 radians.
- Returns:
color a list representing an RGB color
Note
number and choice of colors is fixed, global
selection of angle breakpoints is fixed, global
- trvtool.sortTuples(tuplelist, index, reverse=False)¶
Sort a list of tuples based on specified index.
- Parameters:
tuplelist – a list of tuples
index – the tuple index to pay attention to
reverse (Boolean) – whether to do in reverse order
- Returns:
Sorted list
- trvtool.makeEPSplot(xytlist, filename='tmp.eps', xleft=-1, xright=2, yleft=-1, yright=2, radius=0.02)¶
Write encapselated postscript version of the visualization to a file.
- Parameters:
xytlist –
list of (x,y,t)
x – x coordinate
y – y coordinate
t – angle in radians that the point is off the plane. Must be positive. Used to determine color.
radius – the radius of the disc to represent each point
filename – name of file to write to; should end .eps
xleft – xleft<x bound
xright – x<xright bound
yleft – yleft<y bound
yright – y<yright bound
Writes output to file.
- trvtool.makeRandomSSTensor(dimension=3, rank=1, resolution=2, docomplex=False)¶
Return a random SumSeparableTensor of the specified shape.
- Parameters:
dimension (int, >0) – the physical dimension of the tensor
rank (int, >0) – the separation rank of the tensor
resolution (int, >0) – the resolution of the 1-dimensional vectors
docomplex (Boolean) – if true, make complex
- Returns:
random SumSeparableTensor with the given parameters
- trvtool.makeNearbySSTensor(sstensor, epsilon=0.1)¶
Return a small perturbation of a SumSeparableTensor.
- Parameters:
sstensor (SumSeparableTensor) – the place to start
epsilon – how much to perturb each entry (at most)
Since we perturb each entry in the SumSeparableTensor, we do not produce a ball in the Tensor topology.
Can handle real or complex.
- trvtool.makeLineofSSTensors(sstensor_left, sstensor_right, t_left=-1, t_right=2, numpts=10)¶
Create a line of SumSeparableTensor defined by two.
- Parameters:
sstensor_left (SumSeparableTensor) – one point defining the line
sstensor_right (SumSeparableTensor) – second point defining the line
t_left – the extent of the line to the left; 0 starts at sstensor_left.
t_right – the extent of the line to the right; 1 stops at sstensor_right.
numpts – the number of points to produce. Must be >1
- Returns:
list of numpts instances of SumSeparableTensor
- trvtool.makeGrammMatrix(thinglist)¶
Make a square matrix of inner products
- Parameters:
thinglist – list of things with .innerproduct method
- Returns:
square matrix \(M[i,j]=\langle thinglist[j],thinglist[i]\rangle\). Note that the row index appears in the second argument, which is conjugated in the complex case.
Does not take advantage of symmetry.
- trvtool.makeRHSVector(thinglist, target)¶
Make a vector of inner products with target
- Parameters:
thinglist – list of things with .innerproduct method
target – a single object of the same type
- Returns:
vector \(M[i]=\langle target,thinglist[i]\rangle\). Note that the index appears in the second argument, which is conjugated in the complex case.
- trvtool.findMainGeometry(thinglist)¶
Find the angle #0 to #2 to #1 and ||#1-#2||/||#0-#2||
- parameter thinglist:
list of three things with .innerproduct method
- returns:
the angle formed going from thinglist[0] to thinglist[1] via thinglist[2] and \(||thinglist[1]-thinglist[2]||/||thinglist[0]-thinglist[2]||\)
Angle is based on
\[\cos(\angle_W(T,U)) = \frac{\langle T-W, U-W \rangle}{\|T-W\|\,\|U-W\|}\]Note
Only makes sense for real things, not complex.
- trvtool.SSTensor_to_xyangle(sstensor, cosmainangle, sinmainangle, basepoints, IPmatrix, invIPmatrix)¶
Convert a SumSeparableTensor to its plotting coordinates and angle.
- Parameters:
sstensor – the SumSeparableTensor to plot, must be real
cosmainangle – cosine of the main angle from findMainGeometry
sinmainangle – sine of the main angle from findMainGeometry
basepoints – the 3 SumSeparableTensor-s specifying the plotting plane
IPmatrix – 3x3 matrix produced from basepoints via makeGrammMatrix
invIPmatrix – the inverse of IPmatrix
- Returns (x,y,t):
x is the x coordinate for the plot
y is the y coordinate for the plot
t is the angle that determines the color of the point
The plot is positioned and scaled so that basepoint[2] is at (0,0) and basepoint[0] is at (1,0).
Note
There is a hardwired safety to avoid zero division
- trvtool.SSTensor_to_xyangle_complex(sstensor, basepoints, IPmatrix, invIPmatrix)¶
Convert a SumSeparableTensor to its plotting coordinates and angle, complex.
- Parameters:
sstensor – the SumSeparableTensor to plot, may be complex
basepoints – the 2 SumSeparableTensor-s specifying the plotting complex line
IPmatrix – 2x2 matrix produced from basepoints via makeGrammMatrix
invIPmatrix – the inverse of IPmatrix
- Returns (x,y,t):
x is the x coordinate for the plot
y is the y coordinate for the plot
t is the angle that determines the color of the point
The plot is positioned and scaled so that basepoint[1] is at 0+0j and basepoint[0] is at 1+0j.
- trvtool.xy_to_SSTensor(x, y, cosmainangle, sinmainangle, basepoints)¶
Convert a plotting coordinate (x,y) to a SumSeparableTensor.
- Parameters:
x (float) – the plotting x-coordinate
y (float) – the plotting y-coordinate
cosmainangle – cosine of the main angle from findMainGeometry
sinmainangle – sine of the main angle from findMainGeometry
basepoints – the 3 SumSeparableTensor-s specifying the plotting plane
- Returns:
a tensor at that plotting location. It has the same dimension/resolution as the basepoints, but has rank the sum of the ranks.
- Return type:
For real tensors plotted on a plane, not complex.
- trvtool.xy_to_SSTensor_complex(x, y, basepoints)¶
Convert a plotting coordinate (x,y) to a SumSeparableTensor.
- Parameters:
x (float) – the plotting x-coordinate (represents real)
y (float) – the plotting y-coordinate (represents imaginary)
basepoints – the 2 SumSeparableTensor-s specifying the plotting complex line
- Returns:
a tensor at that plotting location. It has the same dimension/resolution as the basepoints, but has rank the sum of the ranks.
- Return type:
For complex tensors plotted on a complex line
- trvtool.iscovered(xytlist, newpoint, r2)¶
See if a new point is already covered.
Lazy algorithm: detects if center is within some radius of another center.
Generally we want the points in xytlist to have smaller t (angle) than newpoint, but this routine does not check.
- Parameters:
xytlist – list of points already included. The first two entries of each are the coordinates used
newpoint – the new (x,y,t) point to test.
r2 – the square of the radius used to decide. generally use half the radius you will actually plot with.
- Returns:
True if within sqrt(r2) of an existing point, otherwise False
- trvtool.trimcovered(xytlist, radius, verbose=False)¶
Trim the plotting points so that covered ones are discarded.
Lazy algorithm: only assures most of the disc was covered
- Parameters:
xytlist – list of the existing points. Each is (x,y,theta). x,y are the coordinates on the plane and theta the angle off the plane. Smaller angles can cover larger ones.
radius – the radius that will be used for plotting.
- Returns:
a subset of xytlist
- trvtool.trimcovered_recursive(xytlist, radius, directsize=100, x_left=None, x_right=None, y_left=None, y_right=None, verbose=False)¶
Trim the plotting points so that covered ones are discarded.
Lazy algorithm: only assures most of the disc was covered.
Recursive version: first does some geometric splitting to avoid doing N^2 comparisons.
- Parameters:
xytlist – list of the existing points. Each is (x,y,theta). x,y are the coordinates on the plane and theta the angle off the plane. Smaller angles can cover larger ones.
radius – the radius that will be used for plotting.
directsize – if less than this number of points, does not recurse.
x_left – the smallest x-coordinate of any point; solved for if entered as None
x_right – the largestest x-coordinate of any point; solved for if entered as None
y_left – the smallest y-coordinate of any point; solved for if entered as None
y_left – the largest y-coordinate of any point; solved for if entered as None
- Returns:
(interior,edge) two subsets of xytlist
interior – points that could not be covered by a point outside of the [x_left,x_right] by [y_left,y_right] rectangle
edge – points that could be covered
- trvtool.Fit_SSTensor(target, guess, goodenough=1e-05, stuckfactor=1e-06, maxiter=100)¶
Fit to target starting from guess using alternating least squares.
Generally guess will be of lower rank, so we are trying to reduce rank.
- Parameters:
target – SumSeparableTensor to fit to
guess – SumSeparableTensor to fit with. Must have the same dimension and resolution as target
goodenough – if ||target-guess||_2 < goodenough will stop
stuckfactor – if the relative decrease in ||target-guess||_2 becomes < stuckfactor will stop
maxiter – the maximum number of iterations to do in any case
- Returns:
guess,error
guess – the improved guess
error – ||target-guess||_2
- trvtool.Fit_SSTensor_growing(target, rank=1, growiter=2, goodenough=1e-05, stuckfactor=1e-06, maxiter=100)¶
Fit to target using alternating least squares, growing to rank desired.
Generally rank will be lower than the rank of target, so we are trying to reduce rank.
We start with a rank 1 guess, fit using it, increase its rank by 1, fit again, etc. until at the specified rank. We hope this will get us a pretty good approximation and avoid local minima. Then we do extra fitting at the last rank to try to get the optimal approximation.
- Parameters:
target – SumSeparableTensor to fit to
rank (int >0) – The rank allowed for the approwimating SumSeparableTensor.
growiter – the number of iterations to do in any case
goodenough – if ||target-guess||_2 < goodenough will stop the iterations at the final rank
stuckfactor – if the relative decrease in ||target-guess||_2 becomes < stuckfactor will stop the iterations at the final rank
maxiter – the maximum number of iterations to do in any case at the final rank
- Returns:
guess,error
guess – the best approximation found
error – ||target-guess||_2
- trvtool.xytgrid_ALS(cosmainangle, sinmainangle, basepoints, IPmatrix, invIPmatrix, plotrank, x_left, x_right, y_left, y_right, points)¶
Make a grid of xyt points using ALS, over R.
- Parameters:
cosmainangle – cosine of the main angle from findMainGeometry
sinmainangle – sine of the main angle from findMainGeometry
basepoints – the 3 SumSeparableTensor-s specifying the plotting plane
IPmatrix – 3x3 matrix produced from basepoints via makeGrammMatrix
invIPmatrix – the inverse of IPmatrix
plotrank (int >0) – separation rank of points to plot
x_left – left x value on the grid
x_right – right x value on the grid
y_left – left (bottom) y value on the grid
y_right – right (top) y value on the grid
points – the number of point in x and y to use, so we have points*points total
Note hardwired parameters for ALS.
- trvtool.xytgrid_ALS_complex(basepoints, IPmatrix, invIPmatrix, plotrank, x_left, x_right, y_left, y_right, points)¶
Make a grid of xyt points using ALS, over C.
- Parameters:
basepoints – the 2 SumSeparableTensor-s specifying the plotting complex line
IPmatrix – 2x2 matrix produced from basepoints via makeGrammMatrix
invIPmatrix – the inverse of IPmatrix
plotrank (int >0) – separation rank of points to plot
x_left – left x value on the grid
x_right – right x value on the grid
y_left – left (bottom) y value on the grid
y_right – right (top) y value on the grid
points – the number of point in x and y to use, so we have points*points total
Note hardwired parameters for ALS.
Test Routines¶
These routines should be called using the nosetests package with:
nosetests trvtool.py
- trvtool.test_SSTensoradd()¶
Test SumSeparableTensor.__add__.
We check that the concatenation used really corresponds to addition.
- trvtool.test_SSTensorrmul()¶
Test SumSeparableTensor.__rmul__.
We check that the array scalar multiplication used really corresponds to scalar multiplication.
- trvtool.test_SSTensorIP()¶
Test properties of SumSeparableTensor.innerproduct.
\(\langle T,T \rangle >0\)
\(\langle T,U \rangle = \langle U, T \rangle\) for reals
- trvtool.test_findMainGeometry()¶
Test consistency of findMainGeometry.
Switching the first and second tensors should give the same angle and 1/ratio.
- trvtool.test_SSTensor_to_xyangle()¶
Test SSTensor_to_xyangle.
We check that basepoints and combinations of them have angle 0.
- trvtool.test_makeEPSplot()¶
Test makeEPSplot. Creates file test_makeEPSplot.eps to view.
Should produce the 3 corners of a triangle, the 3 midpoints of the sides, and the centroid.
- trvtool.test_StateHolder()¶
Test StateHolder construction and info
Set assertion to false to see printout
- trvtool.test_makeNearbyEPSplot()¶
Test makeNearbySSTensor and makeEPSplot.
Creates file test_makeNearbyEPSplot.eps to view.
Should produce the 3 corners of a triangle and random points near each.
- trvtool.test_makeLineEPSplot()¶
Test makeLineofSSTensors and makeEPSplot.
Creates file test_makeLineEPSplot.eps to view.
Should produce the 3 corners of a triangle and a line connecting 2.
- trvtool.test_Fit_SSTensor()¶
Test Fit_SSTensor.
- trvtool.test_Fit_SSTensor_complex()¶
Test Fit_SSTensor for complex target.
- trvtool.test_trimcovered()¶
Test trimcovered.
Put in definitely covered point and make sure they are removed.
- trvtool.test_xytgrid_ALS()¶
Test xytgrid_ALS