@trebco/treb 23.6.5 → 25.0.0-rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/.eslintignore +8 -0
  2. package/.eslintrc.js +164 -0
  3. package/README-shadow-DOM.md +88 -0
  4. package/README.md +37 -130
  5. package/api-config.json +29 -0
  6. package/api-generator/api-generator-types.ts +82 -0
  7. package/api-generator/api-generator.ts +1172 -0
  8. package/api-generator/package.json +3 -0
  9. package/build/treb-spreadsheet.mjs +14 -0
  10. package/{treb.d.ts → build/treb.d.ts} +285 -269
  11. package/esbuild-custom-element.mjs +336 -0
  12. package/esbuild.js +305 -0
  13. package/package.json +43 -14
  14. package/treb-base-types/package.json +5 -0
  15. package/treb-base-types/src/api_types.ts +36 -0
  16. package/treb-base-types/src/area.ts +583 -0
  17. package/treb-base-types/src/basic_types.ts +45 -0
  18. package/treb-base-types/src/cell.ts +612 -0
  19. package/treb-base-types/src/cells.ts +1066 -0
  20. package/treb-base-types/src/color.ts +124 -0
  21. package/treb-base-types/src/import.ts +71 -0
  22. package/treb-base-types/src/index-standalone.ts +29 -0
  23. package/treb-base-types/src/index.ts +42 -0
  24. package/treb-base-types/src/layout.ts +47 -0
  25. package/treb-base-types/src/localization.ts +187 -0
  26. package/treb-base-types/src/rectangle.ts +145 -0
  27. package/treb-base-types/src/render_text.ts +72 -0
  28. package/treb-base-types/src/style.ts +545 -0
  29. package/treb-base-types/src/table.ts +109 -0
  30. package/treb-base-types/src/text_part.ts +54 -0
  31. package/treb-base-types/src/theme.ts +608 -0
  32. package/treb-base-types/src/union.ts +152 -0
  33. package/treb-base-types/src/value-type.ts +164 -0
  34. package/treb-base-types/style/resizable.css +59 -0
  35. package/treb-calculator/modern.tsconfig.json +11 -0
  36. package/treb-calculator/package.json +5 -0
  37. package/treb-calculator/src/calculator.ts +2546 -0
  38. package/treb-calculator/src/complex-math.ts +558 -0
  39. package/treb-calculator/src/dag/array-vertex.ts +198 -0
  40. package/treb-calculator/src/dag/graph.ts +951 -0
  41. package/treb-calculator/src/dag/leaf_vertex.ts +118 -0
  42. package/treb-calculator/src/dag/spreadsheet_vertex.ts +327 -0
  43. package/treb-calculator/src/dag/spreadsheet_vertex_base.ts +44 -0
  44. package/treb-calculator/src/dag/vertex.ts +352 -0
  45. package/treb-calculator/src/descriptors.ts +162 -0
  46. package/treb-calculator/src/expression-calculator.ts +1069 -0
  47. package/treb-calculator/src/function-error.ts +103 -0
  48. package/treb-calculator/src/function-library.ts +103 -0
  49. package/treb-calculator/src/functions/base-functions.ts +1214 -0
  50. package/treb-calculator/src/functions/checkbox.ts +164 -0
  51. package/treb-calculator/src/functions/complex-functions.ts +253 -0
  52. package/treb-calculator/src/functions/finance-functions.ts +399 -0
  53. package/treb-calculator/src/functions/information-functions.ts +102 -0
  54. package/treb-calculator/src/functions/matrix-functions.ts +182 -0
  55. package/treb-calculator/src/functions/sparkline.ts +335 -0
  56. package/treb-calculator/src/functions/statistics-functions.ts +350 -0
  57. package/treb-calculator/src/functions/text-functions.ts +298 -0
  58. package/treb-calculator/src/index.ts +27 -0
  59. package/treb-calculator/src/notifier-types.ts +59 -0
  60. package/treb-calculator/src/primitives.ts +428 -0
  61. package/treb-calculator/src/utilities.ts +305 -0
  62. package/treb-charts/package.json +5 -0
  63. package/treb-charts/src/chart-functions.ts +156 -0
  64. package/treb-charts/src/chart-types.ts +230 -0
  65. package/treb-charts/src/chart.ts +1288 -0
  66. package/treb-charts/src/index.ts +24 -0
  67. package/treb-charts/src/main.ts +37 -0
  68. package/treb-charts/src/rectangle.ts +52 -0
  69. package/treb-charts/src/renderer.ts +1841 -0
  70. package/treb-charts/src/util.ts +122 -0
  71. package/treb-charts/style/charts.scss +221 -0
  72. package/treb-charts/style/old-charts.scss +250 -0
  73. package/treb-embed/markup/layout.html +137 -0
  74. package/treb-embed/markup/toolbar.html +175 -0
  75. package/treb-embed/modern.tsconfig.json +25 -0
  76. package/treb-embed/src/custom-element/content-types.d.ts +18 -0
  77. package/treb-embed/src/custom-element/global.d.ts +11 -0
  78. package/treb-embed/src/custom-element/spreadsheet-constructor.ts +1227 -0
  79. package/treb-embed/src/custom-element/treb-global.ts +44 -0
  80. package/treb-embed/src/custom-element/treb-spreadsheet-element.ts +52 -0
  81. package/treb-embed/src/embedded-spreadsheet.ts +5362 -0
  82. package/treb-embed/src/index.ts +16 -0
  83. package/treb-embed/src/language-model.ts +41 -0
  84. package/treb-embed/src/options.ts +320 -0
  85. package/treb-embed/src/progress-dialog.ts +228 -0
  86. package/treb-embed/src/selection-state.ts +16 -0
  87. package/treb-embed/src/spinner.ts +42 -0
  88. package/treb-embed/src/toolbar-message.ts +96 -0
  89. package/treb-embed/src/types.ts +167 -0
  90. package/treb-embed/style/autocomplete.scss +103 -0
  91. package/treb-embed/style/dark-theme.scss +114 -0
  92. package/treb-embed/style/defaults.scss +36 -0
  93. package/treb-embed/style/dialog.scss +181 -0
  94. package/treb-embed/style/dropdown-select.scss +101 -0
  95. package/treb-embed/style/formula-bar.scss +193 -0
  96. package/treb-embed/style/grid.scss +374 -0
  97. package/treb-embed/style/layout.scss +424 -0
  98. package/treb-embed/style/mouse-mask.scss +67 -0
  99. package/treb-embed/style/note.scss +92 -0
  100. package/treb-embed/style/overlay-editor.scss +102 -0
  101. package/treb-embed/style/spinner.scss +92 -0
  102. package/treb-embed/style/tab-bar.scss +228 -0
  103. package/treb-embed/style/table.scss +80 -0
  104. package/treb-embed/style/theme-defaults.scss +444 -0
  105. package/treb-embed/style/toolbar.scss +416 -0
  106. package/treb-embed/style/tooltip.scss +68 -0
  107. package/treb-embed/style/treb-icons.scss +130 -0
  108. package/treb-embed/style/treb-spreadsheet-element.scss +20 -0
  109. package/treb-embed/style/z-index.scss +43 -0
  110. package/treb-export/docs/charts.md +68 -0
  111. package/treb-export/modern.tsconfig.json +19 -0
  112. package/treb-export/package.json +4 -0
  113. package/treb-export/src/address-type.ts +77 -0
  114. package/treb-export/src/base-template.ts +22 -0
  115. package/treb-export/src/column-width.ts +85 -0
  116. package/treb-export/src/drawing2/chart-template-components2.ts +389 -0
  117. package/treb-export/src/drawing2/chart2.ts +282 -0
  118. package/treb-export/src/drawing2/column-chart-template2.ts +521 -0
  119. package/treb-export/src/drawing2/donut-chart-template2.ts +296 -0
  120. package/treb-export/src/drawing2/drawing2.ts +355 -0
  121. package/treb-export/src/drawing2/embedded-image.ts +71 -0
  122. package/treb-export/src/drawing2/scatter-chart-template2.ts +555 -0
  123. package/treb-export/src/export-worker/export-worker.ts +99 -0
  124. package/treb-export/src/export-worker/index-modern.ts +22 -0
  125. package/treb-export/src/export2.ts +2204 -0
  126. package/treb-export/src/import2.ts +882 -0
  127. package/treb-export/src/relationship.ts +36 -0
  128. package/treb-export/src/shared-strings2.ts +128 -0
  129. package/treb-export/src/template-2.ts +22 -0
  130. package/treb-export/src/unescape_xml.ts +47 -0
  131. package/treb-export/src/workbook-sheet2.ts +182 -0
  132. package/treb-export/src/workbook-style2.ts +1285 -0
  133. package/treb-export/src/workbook-theme2.ts +88 -0
  134. package/treb-export/src/workbook2.ts +491 -0
  135. package/treb-export/src/xml-utils.ts +201 -0
  136. package/treb-export/template/base/[Content_Types].xml +2 -0
  137. package/treb-export/template/base/_rels/.rels +2 -0
  138. package/treb-export/template/base/docProps/app.xml +2 -0
  139. package/treb-export/template/base/docProps/core.xml +12 -0
  140. package/treb-export/template/base/xl/_rels/workbook.xml.rels +2 -0
  141. package/treb-export/template/base/xl/sharedStrings.xml +2 -0
  142. package/treb-export/template/base/xl/styles.xml +2 -0
  143. package/treb-export/template/base/xl/theme/theme1.xml +2 -0
  144. package/treb-export/template/base/xl/workbook.xml +2 -0
  145. package/treb-export/template/base/xl/worksheets/sheet1.xml +2 -0
  146. package/treb-export/template/base.xlsx +0 -0
  147. package/treb-format/package.json +8 -0
  148. package/treb-format/src/format.test.ts +213 -0
  149. package/treb-format/src/format.ts +942 -0
  150. package/treb-format/src/format_cache.ts +199 -0
  151. package/treb-format/src/format_parser.ts +723 -0
  152. package/treb-format/src/index.ts +25 -0
  153. package/treb-format/src/number_format_section.ts +100 -0
  154. package/treb-format/src/value_parser.ts +337 -0
  155. package/treb-grid/package.json +5 -0
  156. package/treb-grid/src/editors/autocomplete.ts +394 -0
  157. package/treb-grid/src/editors/autocomplete_matcher.ts +260 -0
  158. package/treb-grid/src/editors/formula_bar.ts +473 -0
  159. package/treb-grid/src/editors/formula_editor_base.ts +910 -0
  160. package/treb-grid/src/editors/overlay_editor.ts +511 -0
  161. package/treb-grid/src/index.ts +37 -0
  162. package/treb-grid/src/layout/base_layout.ts +2618 -0
  163. package/treb-grid/src/layout/grid_layout.ts +299 -0
  164. package/treb-grid/src/layout/rectangle_cache.ts +86 -0
  165. package/treb-grid/src/render/selection-renderer.ts +414 -0
  166. package/treb-grid/src/render/svg_header_overlay.ts +93 -0
  167. package/treb-grid/src/render/svg_selection_block.ts +187 -0
  168. package/treb-grid/src/render/tile_renderer.ts +2122 -0
  169. package/treb-grid/src/types/annotation.ts +216 -0
  170. package/treb-grid/src/types/border_constants.ts +34 -0
  171. package/treb-grid/src/types/clipboard_data.ts +31 -0
  172. package/treb-grid/src/types/data_model.ts +334 -0
  173. package/treb-grid/src/types/drag_mask.ts +81 -0
  174. package/treb-grid/src/types/grid.ts +7743 -0
  175. package/treb-grid/src/types/grid_base.ts +3644 -0
  176. package/treb-grid/src/types/grid_command.ts +470 -0
  177. package/treb-grid/src/types/grid_events.ts +124 -0
  178. package/treb-grid/src/types/grid_options.ts +97 -0
  179. package/treb-grid/src/types/grid_selection.ts +60 -0
  180. package/treb-grid/src/types/named_range.ts +369 -0
  181. package/treb-grid/src/types/scale-control.ts +202 -0
  182. package/treb-grid/src/types/serialize_options.ts +72 -0
  183. package/treb-grid/src/types/set_range_options.ts +52 -0
  184. package/treb-grid/src/types/sheet.ts +3099 -0
  185. package/treb-grid/src/types/sheet_types.ts +95 -0
  186. package/treb-grid/src/types/tab_bar.ts +464 -0
  187. package/treb-grid/src/types/tile.ts +59 -0
  188. package/treb-grid/src/types/update_flags.ts +75 -0
  189. package/treb-grid/src/util/dom_utilities.ts +44 -0
  190. package/treb-grid/src/util/fontmetrics2.ts +179 -0
  191. package/treb-grid/src/util/ua.ts +104 -0
  192. package/treb-logo.svg +18 -0
  193. package/treb-parser/package.json +5 -0
  194. package/treb-parser/src/csv-parser.ts +122 -0
  195. package/treb-parser/src/index.ts +25 -0
  196. package/treb-parser/src/md-parser.ts +526 -0
  197. package/treb-parser/src/parser-types.ts +397 -0
  198. package/treb-parser/src/parser.test.ts +298 -0
  199. package/treb-parser/src/parser.ts +2673 -0
  200. package/treb-utils/package.json +5 -0
  201. package/treb-utils/src/dispatch.ts +57 -0
  202. package/treb-utils/src/event_source.ts +147 -0
  203. package/treb-utils/src/ievent_source.ts +33 -0
  204. package/treb-utils/src/index.ts +31 -0
  205. package/treb-utils/src/measurement.ts +174 -0
  206. package/treb-utils/src/resizable.ts +160 -0
  207. package/treb-utils/src/scale.ts +137 -0
  208. package/treb-utils/src/serialize_html.ts +124 -0
  209. package/treb-utils/src/template.ts +70 -0
  210. package/treb-utils/src/validate_uri.ts +61 -0
  211. package/tsconfig.json +10 -0
  212. package/tsproject.json +30 -0
  213. package/util/license-plugin-esbuild.js +86 -0
  214. package/util/list-css-vars.sh +46 -0
  215. package/README-esm.md +0 -37
  216. package/treb-bundle.css +0 -2
  217. package/treb-bundle.mjs +0 -15
@@ -0,0 +1,558 @@
1
+ /*
2
+ * This file is part of TREB.
3
+ *
4
+ * TREB is free software: you can redistribute it and/or modify it under the
5
+ * terms of the GNU General Public License as published by the Free Software
6
+ * Foundation, either version 3 of the License, or (at your option) any
7
+ * later version.
8
+ *
9
+ * TREB is distributed in the hope that it will be useful, but WITHOUT ANY
10
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12
+ * details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License along
15
+ * with TREB. If not, see <https://www.gnu.org/licenses/>.
16
+ *
17
+ * Copyright 2022-2023 trebco, llc.
18
+ * info@treb.app
19
+ *
20
+ */
21
+
22
+ import type { Complex } from 'treb-base-types/src';
23
+
24
+ export interface ComplexMatrixType {
25
+ array: Complex[][];
26
+ m: number;
27
+ n: number;
28
+ error?: boolean;
29
+ }
30
+
31
+ export interface RealMatrixType {
32
+ array: number[][];
33
+ m: number;
34
+ n: number;
35
+ error?: boolean;
36
+ }
37
+
38
+ /** returns a aquare complex matrix of size n, initialized to 0 */
39
+ const ComplexMatrix = (n: number): ComplexMatrixType => {
40
+ const mat: ComplexMatrixType = {
41
+ m: n, n, array: [],
42
+ };
43
+ for (let i = 0; i < n; i++) {
44
+ const row: Complex[] = [];
45
+ for (let j = 0; j < n; j++) {
46
+ row.push({real: 0, imaginary: 0});
47
+ }
48
+ mat.array.push(row);
49
+ }
50
+ return mat;
51
+ }
52
+
53
+ /** returns a aquare complex matrix of size n, initialized to 0 */
54
+ const RealMatrix = (n: number): RealMatrixType => {
55
+ const mat: RealMatrixType = {
56
+ m: n, n, array: [],
57
+ };
58
+ for (let i = 0; i < n; i++) {
59
+ const row: number[] = [];
60
+ for (let j = 0; j < n; j++) {
61
+ row.push(0);
62
+ }
63
+ mat.array.push(row);
64
+ }
65
+ return mat;
66
+ }
67
+
68
+ // not used? (...)
69
+
70
+ /* * returns the identity matrix of size n, as complex * /
71
+ const ComplexIdentity = (n: number): ComplexMatrixType => {
72
+ const mat = ComplexMatrix(n);
73
+ for (let i = 0; i < n; i++) {
74
+ mat.array[i][i].real = 1;
75
+ }
76
+ return mat;
77
+ };
78
+ */
79
+
80
+ export const PolarToRectangular = (a: { r: number, theta: number }): Complex => {
81
+
82
+ const { r, theta } = a;
83
+
84
+ const real = r * Math.cos(theta);
85
+ const imaginary = r * Math.sin(theta);
86
+
87
+ // console.info("P2R", `r ${r} theta (o) ${theta * 57.29577951308232}`, '->', `${real||0}${imaginary < 0 ? '' : '+'}${imaginary}i`);
88
+
89
+ return { real, imaginary }
90
+ };
91
+
92
+ export const RectangularToPolar = (value: Complex): { r: number, theta: number } => {
93
+
94
+ const r = Math.sqrt(value.real * value.real + value.imaginary * value.imaginary);
95
+ const theta = Math.atan2(value.imaginary, value.real);
96
+
97
+ // console.info("R2P", `${value.real||0}${value.imaginary < 0 ? '' : '+'}${value.imaginary}i`, '->', `r ${r} theta (o) ${theta * 57.29577951308232}`);
98
+
99
+ return { r, theta };
100
+ };
101
+
102
+ export const Multiply = (a: Complex, b: Complex): Complex => {
103
+ return {
104
+ real: (a.real * b.real) - (a.imaginary * b.imaginary),
105
+ imaginary: a.real * b.imaginary + a.imaginary * b.real,
106
+ }
107
+ };
108
+
109
+ export const RealSum = (a: RealMatrixType, b: RealMatrixType): RealMatrixType => {
110
+
111
+ const array: number[][] = [];
112
+ for (let i = 0; i < a.m; i++) {
113
+ const row: number[] = [];
114
+ for (let j = 0; j < a.n; j++) {
115
+ row.push(a.array[i][j] + b.array[i][j]);
116
+ }
117
+ array.push(row);
118
+ }
119
+ return {m: a.m, n: a.n, array};
120
+
121
+ };
122
+
123
+ export const RealProduct = (a: RealMatrixType, b: RealMatrixType): RealMatrixType => {
124
+ const array: number[][] = [];
125
+
126
+ for (let i = 0; i < a.m; i++) {
127
+ const row: number[] = [];
128
+ for (let j = 0; j < b.n; j++) {
129
+ let sum = 0;
130
+ for (let k = 0; k < a.n; k++) {
131
+ sum += a.array[i][k] * b.array[k][j];
132
+ }
133
+ row.push(sum);
134
+ }
135
+ array.push(row);
136
+ }
137
+
138
+ return { array, m: a.m, n: b.n };
139
+
140
+ };
141
+
142
+ export const ComplexProduct = (a: ComplexMatrixType, b: ComplexMatrixType): Complex[][] => {
143
+
144
+ const result: Complex[][] = [];
145
+
146
+ for (let i = 0; i < a.m; i++) {
147
+ const row: Complex[] = [];
148
+ for (let j = 0; j < b.n; j++) {
149
+ const sum = { real: 0, imaginary: 0 };
150
+ for (let k = 0; k < a.n; k++) {
151
+ // const product = Multiply(a.array[i][k], b.array[k][j]);
152
+ sum.real += ((a.array[i][k].real * b.array[k][j].real) - (a.array[i][k].imaginary * b.array[k][j].imaginary));
153
+ sum.imaginary += (a.array[i][k].real * b.array[k][j].imaginary + a.array[i][k].imaginary * b.array[k][j].real);
154
+ }
155
+ row.push(sum);
156
+ }
157
+ result.push(row);
158
+ }
159
+
160
+ return result;
161
+
162
+ };
163
+
164
+ interface SplitFlags {
165
+
166
+ /** the matrix has some real values != 0 */
167
+ real_values: boolean;
168
+
169
+ /** the matrix has some imaginary values != 0 */
170
+ imaginary_values: boolean;
171
+
172
+ /** the matrix is square */
173
+ square: boolean;
174
+
175
+ /** the matrix has unit diagonal */
176
+ unit_diagonal: boolean;
177
+
178
+ }
179
+
180
+ /**
181
+ * this function DOES NOT check if the matrix is square, because it's
182
+ * recursive and we don't want to do that every time. check before you
183
+ * call it.
184
+ */
185
+ export const ComplexDeterminant = (matrix: ComplexMatrixType): Complex => {
186
+
187
+ const det: Complex = { real: 0, imaginary: 0 };
188
+ const n = matrix.n;
189
+
190
+ if (n == 2) {
191
+
192
+ const a = Multiply(matrix.array[0][0], matrix.array[1][1]);
193
+ const b = Multiply(matrix.array[1][0], matrix.array[0][1]);
194
+
195
+ return {
196
+ real: a.real - b.real,
197
+ imaginary: a.imaginary - b.imaginary,
198
+ };
199
+
200
+ }
201
+
202
+ const submatrix = ComplexMatrix(matrix.n);
203
+
204
+ for (let x = 0; x < n; x++) {
205
+ let subi = 0;
206
+ for (let i = 1; i < n; i++) {
207
+ let subj = 0;
208
+ for (let j = 0; j < n; j++) {
209
+ if (j == x) {
210
+ continue;
211
+ }
212
+ submatrix.array[subi][subj] = {...matrix.array[i][j]};
213
+ subj++;
214
+ }
215
+ subi++;
216
+ }
217
+
218
+ submatrix.m = submatrix.n = n - 1;
219
+
220
+ const factor = Math.pow(-1, x)
221
+ const product = Multiply({
222
+ real: matrix.array[0][x].real * factor,
223
+ imaginary: matrix.array[0][x].imaginary * factor,
224
+ }, ComplexDeterminant(submatrix));
225
+
226
+ det.real += product.real;
227
+ det.imaginary += product.imaginary;
228
+
229
+ }
230
+
231
+ return det;
232
+
233
+ };
234
+
235
+ export const RealDeterminant = (matrix: RealMatrixType): number => {
236
+
237
+ let det = 0;
238
+ const n = matrix.n;
239
+ const submatrix = RealMatrix(n);
240
+
241
+ if (n === 2) {
242
+ return( (matrix.array[0][0] * matrix.array[1][1]) - (matrix.array[1][0] * matrix.array[0][1]));
243
+ }
244
+
245
+ for (let x = 0; x < n; x++) {
246
+ let subi = 0;
247
+ for (let i = 1; i < n; i++) {
248
+ let subj = 0;
249
+ for (let j = 0; j < n; j++) {
250
+ if (j == x)
251
+ continue;
252
+ submatrix.array[subi][subj] = matrix.array[i][j];
253
+ subj++;
254
+ }
255
+ subi++;
256
+ }
257
+
258
+ console.info(JSON.stringify(submatrix.array, undefined, 2));
259
+
260
+ submatrix.n = submatrix.m = n - 1;
261
+ det = det + (Math.pow(-1, x) * matrix.array[0][x] * RealDeterminant(submatrix));
262
+ }
263
+
264
+ // console.info("N", n, "det", det);
265
+
266
+ return det;
267
+
268
+ };
269
+
270
+ /**
271
+ * split a complex matrix into two real matrices representing the real and imaginary parts
272
+ */
273
+ const Split = (matrix: ComplexMatrixType): {real: RealMatrixType, imaginary: RealMatrixType, flags: SplitFlags} => {
274
+
275
+ const flags = {
276
+ real_values: false,
277
+ imaginary_values: false,
278
+ square: (matrix.m === matrix.n),
279
+ unit_diagonal: true,
280
+ };
281
+
282
+ const real: RealMatrixType = {
283
+ m: matrix.m,
284
+ n: matrix.n,
285
+ array: [],
286
+ };
287
+
288
+ const imaginary: RealMatrixType = {
289
+ m: matrix.m,
290
+ n: matrix.n,
291
+ array: [],
292
+ };
293
+
294
+ for (let i = 0; i< matrix.m; i++) {
295
+ const row = matrix.array[i];
296
+ const real_row: number[] = [];
297
+ const imaginary_row: number[] = [];
298
+
299
+ for (let j = 0; j< matrix.n; j++) {
300
+
301
+ if (row[j].real) { flags.real_values = true; }
302
+ if (row[j].imaginary) { flags.imaginary_values = true; }
303
+
304
+ if (j === i && flags.unit_diagonal) {
305
+ if (row[j].real !== 1 || row[j].imaginary !== 0) {
306
+ flags.unit_diagonal = false;
307
+ }
308
+ }
309
+
310
+ real_row.push(row[j].real);
311
+ imaginary_row.push(row[j].imaginary);
312
+ }
313
+
314
+ real.array.push(real_row);
315
+ imaginary.array.push(imaginary_row);
316
+ }
317
+
318
+ return {real, imaginary, flags};
319
+
320
+ };
321
+
322
+ /**
323
+ * clone a matrix using slice() on rows? hope this is faster than JSONJSON.
324
+ *
325
+ * actually if you care about perf, should probably not use functional-style
326
+ */
327
+ const CloneReal = (matrix: RealMatrixType): RealMatrixType => {
328
+ const array = matrix.array.map(row => row.slice(0));
329
+ return { m: matrix.m, n: matrix.n, array };
330
+ };
331
+
332
+ export const RealInverse = (matrix: RealMatrixType): RealMatrixType|undefined => {
333
+
334
+ if (matrix.m !== matrix.n) {
335
+ return undefined;
336
+ }
337
+
338
+ const result = CloneReal(matrix);
339
+
340
+ // FIXME: exception on !square, zero in diagonal, &c
341
+
342
+ const M = result.array;
343
+
344
+ let sum = 0;
345
+ let i = 0;
346
+ let j = 0;
347
+ let k = 0;
348
+
349
+ const order = matrix.m;
350
+
351
+ for (i = 1; i < order; i++) M[0][i] /= M[0][0]; // normalize row 0
352
+
353
+ for (i = 1; i < order; i++) {
354
+ for (j = i; j < order; j++) { // do a column of L
355
+ sum = 0;
356
+ for (k = 0; k < i; k++) {
357
+ sum += M[j][k] * M[k][i];
358
+ }
359
+ M[j][i] -= sum;
360
+ }
361
+ if (i == order - 1) continue;
362
+ for (j = i + 1; j < order; j++) { // do a row of U
363
+ sum = 0;
364
+ for (k = 0; k < i; k++) {
365
+ sum += M[i][k] * M[k][j];
366
+ }
367
+ M[i][j] = (M[i][j] - sum) / M[i][i];
368
+ }
369
+ }
370
+
371
+ for (i = 0; i < order; i++) { // invert L
372
+ for (j = i; j < order; j++) {
373
+ let x = 1;
374
+ if (i != j) {
375
+ x = 0;
376
+ for (k = i; k < j; k++) {
377
+ x -= M[j][k] * M[k][i];
378
+ }
379
+ }
380
+ M[j][i] = x / M[j][j];
381
+ }
382
+ }
383
+ for (i = 0; i < order; i++) { // invert U
384
+ for (j = i; j < order; j++) {
385
+ if (i == j) continue;
386
+ sum = 0;
387
+ for (k = i; k < j; k++) {
388
+ sum += M[k][j] * ((i == k) ? 1 : M[i][k]);
389
+ }
390
+ M[i][j] = -sum;
391
+ }
392
+ }
393
+ for (i = 0; i < order; i++) { // final inversion
394
+ for (j = 0; j < order; j++) {
395
+ sum = 0;
396
+ for (k = ((i > j) ? i : j); k < order; k++) {
397
+ sum += ((j == k) ? 1 : M[j][k]) * M[k][i];
398
+ }
399
+ M[j][i] = sum;
400
+ }
401
+ }
402
+
403
+ return result;
404
+
405
+ };
406
+
407
+ /**
408
+ * returns the inverse of a complex matrix. the first step in this is
409
+ * to split into {real, imaginary} and then invert the real matrix. we
410
+ * can use that as a shortcut if there are no imaginary values, just return
411
+ * the inverted real matrix (here converted to complex, but we don't necessarily
412
+ * need to do that)
413
+ *
414
+ * @param a
415
+ * @returns
416
+ */
417
+ export const MatrixInverse = (a: ComplexMatrixType): Complex[][] | undefined => {
418
+
419
+ // FIXME: support for this algorithm?
420
+
421
+ const result: Complex[][] = [];
422
+
423
+ if (a.m !== a.n) { return undefined; }
424
+
425
+ const { real, imaginary, flags } = Split(a);
426
+
427
+ const C1 = RealInverse(real);
428
+
429
+ if (!C1) { return undefined; }
430
+
431
+ if (!flags.imaginary_values) {
432
+
433
+ // shortcut,
434
+
435
+ for (let i = 0; i < a.m; i++) {
436
+ const row: Complex[] = [];
437
+ for (let j = 0; j < a.n; j++) {
438
+ row.push({
439
+ real: C1.array[i][j],
440
+ imaginary: 0,
441
+ });
442
+ }
443
+ result.push(row);
444
+ }
445
+
446
+ return result;
447
+ }
448
+
449
+ const C2 = RealProduct(C1, imaginary);
450
+ const C3 = RealProduct(imaginary, C2);
451
+ const C4 = RealSum(real, C3);
452
+ const C5 = RealInverse(C4);
453
+
454
+ if (!C5) { return undefined; }
455
+
456
+ const C6 = RealProduct(C2, C5);
457
+
458
+ for (let i = 0; i < a.m; i++) {
459
+ const row: Complex[] = [];
460
+ for (let j = 0; j < a.n; j++) {
461
+ row.push({
462
+ real: C5.array[i][j],
463
+ imaginary: -C6.array[i][j],
464
+ });
465
+ }
466
+ result.push(row);
467
+ }
468
+
469
+ return result;
470
+
471
+ };
472
+
473
+ export const Divide = (a: Complex, b: Complex): Complex => {
474
+
475
+ const conjugate = { real: b.real, imaginary: -b.imaginary };
476
+ const numerator = Multiply(a, conjugate);
477
+ const denominator = Multiply(b, conjugate);
478
+
479
+ return {
480
+ real: numerator.real / denominator.real,
481
+ imaginary: numerator.imaginary / denominator.real,
482
+ };
483
+
484
+ };
485
+
486
+ export const Exp = (value: Complex): Complex => {
487
+
488
+ const a = value.real || 0;
489
+ const b = value.imaginary || 0;
490
+
491
+ // e^(a + bi) = e^a * e^ib = e^a * (cos b - i sin b)
492
+
493
+ return Multiply(
494
+ { real: Math.exp(a), imaginary: 0, },
495
+ { real: Math.cos(b), imaginary: Math.sin(b), },
496
+ );
497
+
498
+ };
499
+
500
+ /**
501
+ * from polar form, the principal value is
502
+ * Log z = ln r + iθ
503
+ */
504
+ export const Log = (value: Complex): Complex => {
505
+ const polar = RectangularToPolar(value);
506
+ return {
507
+ real: Math.log(polar.r),
508
+ imaginary: polar.theta,
509
+ };
510
+ }
511
+
512
+ /**
513
+ * returns a^b where a and b are (possibly) complex
514
+ */
515
+ export const Power = (a: Complex, b: Complex): Complex => {
516
+
517
+ if (!b.imaginary) {
518
+
519
+ // we could potentially clean up some simple cases, to help
520
+ // with numerical stability. in particular, I'm thinking about
521
+ // square roots of reals (possibly negative).
522
+
523
+ /*
524
+ if (b.real === .5 && !a.imaginary) {
525
+ if (a.real < 0) {
526
+ return {
527
+ real: 0,
528
+ imaginary: Math.sqrt(-a.real),
529
+ };
530
+ }
531
+ return {
532
+ real: Math.sqrt(a.real),
533
+ imaginary: 0,
534
+ };
535
+ }
536
+ */
537
+
538
+ const polar = RectangularToPolar(a);
539
+ const value = PolarToRectangular({
540
+ r: Math.pow(polar.r, b.real),
541
+ theta: polar.theta * b.real,
542
+ });
543
+
544
+ return value;
545
+
546
+ }
547
+ else {
548
+
549
+ // in this case,
550
+ // (a + bi)^(c + di) = exp((c + di) * Log(a + bi))
551
+
552
+ return Exp(Multiply(b, Log(a)));
553
+
554
+ }
555
+
556
+
557
+ };
558
+