xref: /petsc/share/petsc/saws/js/matrixTex.js (revision ad4c700a6ebc38b60b2fdd96cddbb3030870786f)
1//gives users a visual of the nested matrices
2//instead of using subscript of subscript of subscript, etc. simply put the id of the matrix in the first subscript level. for example, A_{010}
3
4//this function is recursive and should always be called with parameter "0"
5//weird because the longer the string is, the more deep the recursion is. "0" is the top level. digits are only added. never removed
6function getMatrixTex(data, endtag) {
7
8    if(data[endtag] == undefined)
9        return;
10
11    //case 1: not logstruc. base case.
12    if(!data[endtag].logstruc) {
13        //return the appropriate tex
14
15        var depth = getNumUnderscores(endtag);
16        var color = colors[depth%colors.length];
17
18        var subscript = endtag.replace(/_/g, ",");
19        return "{\\color{"+color+"}" + "\\left[A_{" + subscript + "}" + "\\right]}";
20    }
21
22    //case 2: has more children. recursive case.
23    else {
24        var depth = getNumUnderscores(endtag);
25        var color = colors[depth%colors.length];
26
27        var ret = "";
28
29        var blocks = data[endtag].pc_fieldsplit_blocks;
30        var childrenTex = "";
31
32        var justify = "";
33        for(var i=0; i<blocks-1; i++) {
34            justify += "c@{}";
35        }
36        justify += "c";
37
38        ret += "\\color{"+color+"}" + "\\left[" + "\\color{black}" + "\\begin{array}{"+justify+"}";//begin the matrix
39
40        for(var i=0; i<blocks; i++) {//NEED TO ADD STARS
41            for(var j=0; j<i; j++) {//add the stars that go BEFORE the diagonal element
42                ret += "* & ";
43            }
44
45            var childEndtag = endtag + "_" + i;
46            //lay out children
47            var childTex = getMatrixTex(data, childEndtag);
48            if(childTex != "")
49                ret += getMatrixTex(data, childEndtag);
50            else {
51                var subscript = childEndtag.replace(/_/g, ",");
52                ret += "A_{" + subscript + "}";
53            }
54
55            for(var j=i+1; j<blocks; j++) {//add the stars that go AFTER the diagonal element
56                ret += "& *";
57            }
58            ret += "\\\\"; //add the backslash indicating the next matrix row
59        }
60
61        ret += "\\end{array}\\right]";//close the matrix
62        return ret;
63    }
64
65}
66
67var bjacobiSplits = [];//global variable that keeps track of how the bjacobi blocks were split
68
69//this function displays a visual of the nested pc=bjacobi block structure and/or nested pc=ksp block structure
70//this function is recursive and should almost always be called with parameter "0" like so: getSpecificMatrixTex("0")
71function getSpecificMatrixTex(data, endtag) {
72
73    if(endtag == "0") {//reset bjacobi splits data
74        delete bjacobiSplits;
75        bjacobiSplits.length=0;
76    }
77
78    var ret = "";//returned value
79
80    if(data[endtag] == undefined) //invalid matrix
81        return ret;
82
83    var pc    = data[endtag].pc_type;
84    var ksp   = data[endtag].ksp_type;
85
86    //case 1: non-recursive base case
87    if(pc != "ksp" && pc != "bjacobi") {
88        return ksp+"/"+pc;//don't put braces at the very end
89    }
90
91    //case 2: pc=ksp recursive case
92    if(pc == "ksp") {
93        ret += "\\left.\\begin{aligned}";
94
95        endtag += "_0";
96
97        //ksp is a composite pc so there will be more options
98
99        ret += getSpecificMatrixTex(endtag);
100        ret += "\\end{aligned}\\right\\}"+ksp+"/"+pc;
101        return ret;
102    }
103
104    //case 3: pc=bjacobi recursive case
105    else if(pc == "bjacobi") {
106        ret += "\\left.\\begin{aligned}";
107
108        endtag += "_0";
109
110        var blocks = data[endtag].pc_bjacobi_blocks;
111
112        //record that we split
113        var idx = bjacobiSplits.length;
114        bjacobiSplits[idx] = blocks;
115
116        var childTex = getSpecificMatrixTex(endtag);
117        for(var i=0; i<blocks; i++)
118            ret += childTex + "\\\\";
119        ret += "\\end{aligned}\\right\\}" + ksp+"/"+pc;
120        return ret;
121    }
122
123    return ret;
124}
125
126//this function generates the corresponding matrix for the specific matrix diagram
127//this function is recursive and should always be called with parameter 0 like so: getSpecificMatrixTex2(0)
128function getSpecificMatrixTex2(index) {
129
130    //case 1: matrix was not split
131    if(bjacobiSplits.length == 0) {
132        return "\\left[ \\begin{array}{c} * \\end{array}\\right]";
133    }
134
135    //case 2: base case
136    else if(index >= bjacobiSplits.length) {
137        return "\\left[ \\begin{array}{c} * \\end{array}\\right]";
138    }
139
140    //case 3: recursive case
141    else {
142        var ret = "";
143
144        var blocks = bjacobiSplits[index];
145        var innerTex = "";
146
147        var justify = "";
148        for(var i=0; i<blocks-1; i++) {
149            justify += "c@{}";
150        }
151        justify += "c";
152
153        ret += "\\left[ \\begin{array}{"+justify+"}";//begin the matrix
154
155        innerTex = getSpecificMatrixTex2(index+1);
156
157        for(var i=0; i<blocks; i++) {//iterate thru entire square matrix row by row
158            for(var j=0; j<i; j++) {//add the stars that go BEFORE the diagonal element
159                ret += "* & ";
160            }
161
162            ret += innerTex;
163
164            for(var j=i+1; j<blocks; j++) {//add the stars that go AFTER the diagonal element
165                ret += "& *";
166            }
167            ret += "\\\\"; //add the backslash indicating the next matrix row
168        }
169
170        ret += "\\end{array}\\right]";//close the matrix
171
172        return ret;
173    }
174
175
176}
177