@trebco/treb 23.6.2 → 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.
- package/.eslintignore +8 -0
- package/.eslintrc.js +164 -0
- package/README-shadow-DOM.md +88 -0
- package/README.md +37 -130
- package/api-config.json +29 -0
- package/api-generator/api-generator-types.ts +82 -0
- package/api-generator/api-generator.ts +1172 -0
- package/api-generator/package.json +3 -0
- package/build/treb-spreadsheet.mjs +14 -0
- package/{treb.d.ts → build/treb.d.ts} +293 -299
- package/esbuild-custom-element.mjs +336 -0
- package/esbuild.js +305 -0
- package/package.json +43 -14
- package/treb-base-types/package.json +5 -0
- package/treb-base-types/src/api_types.ts +36 -0
- package/treb-base-types/src/area.ts +583 -0
- package/treb-base-types/src/basic_types.ts +45 -0
- package/treb-base-types/src/cell.ts +612 -0
- package/treb-base-types/src/cells.ts +1066 -0
- package/treb-base-types/src/color.ts +124 -0
- package/treb-base-types/src/import.ts +71 -0
- package/treb-base-types/src/index-standalone.ts +29 -0
- package/treb-base-types/src/index.ts +42 -0
- package/treb-base-types/src/layout.ts +47 -0
- package/treb-base-types/src/localization.ts +187 -0
- package/treb-base-types/src/rectangle.ts +145 -0
- package/treb-base-types/src/render_text.ts +72 -0
- package/treb-base-types/src/style.ts +545 -0
- package/treb-base-types/src/table.ts +109 -0
- package/treb-base-types/src/text_part.ts +54 -0
- package/treb-base-types/src/theme.ts +608 -0
- package/treb-base-types/src/union.ts +152 -0
- package/treb-base-types/src/value-type.ts +164 -0
- package/treb-base-types/style/resizable.css +59 -0
- package/treb-calculator/modern.tsconfig.json +11 -0
- package/treb-calculator/package.json +5 -0
- package/treb-calculator/src/calculator.ts +2546 -0
- package/treb-calculator/src/complex-math.ts +558 -0
- package/treb-calculator/src/dag/array-vertex.ts +198 -0
- package/treb-calculator/src/dag/graph.ts +951 -0
- package/treb-calculator/src/dag/leaf_vertex.ts +118 -0
- package/treb-calculator/src/dag/spreadsheet_vertex.ts +327 -0
- package/treb-calculator/src/dag/spreadsheet_vertex_base.ts +44 -0
- package/treb-calculator/src/dag/vertex.ts +352 -0
- package/treb-calculator/src/descriptors.ts +162 -0
- package/treb-calculator/src/expression-calculator.ts +1069 -0
- package/treb-calculator/src/function-error.ts +103 -0
- package/treb-calculator/src/function-library.ts +103 -0
- package/treb-calculator/src/functions/base-functions.ts +1214 -0
- package/treb-calculator/src/functions/checkbox.ts +164 -0
- package/treb-calculator/src/functions/complex-functions.ts +253 -0
- package/treb-calculator/src/functions/finance-functions.ts +399 -0
- package/treb-calculator/src/functions/information-functions.ts +102 -0
- package/treb-calculator/src/functions/matrix-functions.ts +182 -0
- package/treb-calculator/src/functions/sparkline.ts +335 -0
- package/treb-calculator/src/functions/statistics-functions.ts +350 -0
- package/treb-calculator/src/functions/text-functions.ts +298 -0
- package/treb-calculator/src/index.ts +27 -0
- package/treb-calculator/src/notifier-types.ts +59 -0
- package/treb-calculator/src/primitives.ts +428 -0
- package/treb-calculator/src/utilities.ts +305 -0
- package/treb-charts/package.json +5 -0
- package/treb-charts/src/chart-functions.ts +156 -0
- package/treb-charts/src/chart-types.ts +230 -0
- package/treb-charts/src/chart.ts +1288 -0
- package/treb-charts/src/index.ts +24 -0
- package/treb-charts/src/main.ts +37 -0
- package/treb-charts/src/rectangle.ts +52 -0
- package/treb-charts/src/renderer.ts +1841 -0
- package/treb-charts/src/util.ts +122 -0
- package/treb-charts/style/charts.scss +221 -0
- package/treb-charts/style/old-charts.scss +250 -0
- package/treb-embed/markup/layout.html +137 -0
- package/treb-embed/markup/toolbar.html +175 -0
- package/treb-embed/modern.tsconfig.json +25 -0
- package/treb-embed/src/custom-element/content-types.d.ts +18 -0
- package/treb-embed/src/custom-element/global.d.ts +11 -0
- package/treb-embed/src/custom-element/spreadsheet-constructor.ts +1227 -0
- package/treb-embed/src/custom-element/treb-global.ts +44 -0
- package/treb-embed/src/custom-element/treb-spreadsheet-element.ts +52 -0
- package/treb-embed/src/embedded-spreadsheet.ts +5362 -0
- package/treb-embed/src/index.ts +16 -0
- package/treb-embed/src/language-model.ts +41 -0
- package/treb-embed/src/options.ts +320 -0
- package/treb-embed/src/progress-dialog.ts +228 -0
- package/treb-embed/src/selection-state.ts +16 -0
- package/treb-embed/src/spinner.ts +42 -0
- package/treb-embed/src/toolbar-message.ts +96 -0
- package/treb-embed/src/types.ts +167 -0
- package/treb-embed/style/autocomplete.scss +103 -0
- package/treb-embed/style/dark-theme.scss +114 -0
- package/treb-embed/style/defaults.scss +36 -0
- package/treb-embed/style/dialog.scss +181 -0
- package/treb-embed/style/dropdown-select.scss +101 -0
- package/treb-embed/style/formula-bar.scss +193 -0
- package/treb-embed/style/grid.scss +374 -0
- package/treb-embed/style/layout.scss +424 -0
- package/treb-embed/style/mouse-mask.scss +67 -0
- package/treb-embed/style/note.scss +92 -0
- package/treb-embed/style/overlay-editor.scss +102 -0
- package/treb-embed/style/spinner.scss +92 -0
- package/treb-embed/style/tab-bar.scss +228 -0
- package/treb-embed/style/table.scss +80 -0
- package/treb-embed/style/theme-defaults.scss +444 -0
- package/treb-embed/style/toolbar.scss +416 -0
- package/treb-embed/style/tooltip.scss +68 -0
- package/treb-embed/style/treb-icons.scss +130 -0
- package/treb-embed/style/treb-spreadsheet-element.scss +20 -0
- package/treb-embed/style/z-index.scss +43 -0
- package/treb-export/docs/charts.md +68 -0
- package/treb-export/modern.tsconfig.json +19 -0
- package/treb-export/package.json +4 -0
- package/treb-export/src/address-type.ts +77 -0
- package/treb-export/src/base-template.ts +22 -0
- package/treb-export/src/column-width.ts +85 -0
- package/treb-export/src/drawing2/chart-template-components2.ts +389 -0
- package/treb-export/src/drawing2/chart2.ts +282 -0
- package/treb-export/src/drawing2/column-chart-template2.ts +521 -0
- package/treb-export/src/drawing2/donut-chart-template2.ts +296 -0
- package/treb-export/src/drawing2/drawing2.ts +355 -0
- package/treb-export/src/drawing2/embedded-image.ts +71 -0
- package/treb-export/src/drawing2/scatter-chart-template2.ts +555 -0
- package/treb-export/src/export-worker/export-worker.ts +99 -0
- package/treb-export/src/export-worker/index-modern.ts +22 -0
- package/treb-export/src/export2.ts +2204 -0
- package/treb-export/src/import2.ts +882 -0
- package/treb-export/src/relationship.ts +36 -0
- package/treb-export/src/shared-strings2.ts +128 -0
- package/treb-export/src/template-2.ts +22 -0
- package/treb-export/src/unescape_xml.ts +47 -0
- package/treb-export/src/workbook-sheet2.ts +182 -0
- package/treb-export/src/workbook-style2.ts +1285 -0
- package/treb-export/src/workbook-theme2.ts +88 -0
- package/treb-export/src/workbook2.ts +491 -0
- package/treb-export/src/xml-utils.ts +201 -0
- package/treb-export/template/base/[Content_Types].xml +2 -0
- package/treb-export/template/base/_rels/.rels +2 -0
- package/treb-export/template/base/docProps/app.xml +2 -0
- package/treb-export/template/base/docProps/core.xml +12 -0
- package/treb-export/template/base/xl/_rels/workbook.xml.rels +2 -0
- package/treb-export/template/base/xl/sharedStrings.xml +2 -0
- package/treb-export/template/base/xl/styles.xml +2 -0
- package/treb-export/template/base/xl/theme/theme1.xml +2 -0
- package/treb-export/template/base/xl/workbook.xml +2 -0
- package/treb-export/template/base/xl/worksheets/sheet1.xml +2 -0
- package/treb-export/template/base.xlsx +0 -0
- package/treb-format/package.json +8 -0
- package/treb-format/src/format.test.ts +213 -0
- package/treb-format/src/format.ts +942 -0
- package/treb-format/src/format_cache.ts +199 -0
- package/treb-format/src/format_parser.ts +723 -0
- package/treb-format/src/index.ts +25 -0
- package/treb-format/src/number_format_section.ts +100 -0
- package/treb-format/src/value_parser.ts +337 -0
- package/treb-grid/package.json +5 -0
- package/treb-grid/src/editors/autocomplete.ts +394 -0
- package/treb-grid/src/editors/autocomplete_matcher.ts +260 -0
- package/treb-grid/src/editors/formula_bar.ts +473 -0
- package/treb-grid/src/editors/formula_editor_base.ts +910 -0
- package/treb-grid/src/editors/overlay_editor.ts +511 -0
- package/treb-grid/src/index.ts +37 -0
- package/treb-grid/src/layout/base_layout.ts +2618 -0
- package/treb-grid/src/layout/grid_layout.ts +299 -0
- package/treb-grid/src/layout/rectangle_cache.ts +86 -0
- package/treb-grid/src/render/selection-renderer.ts +414 -0
- package/treb-grid/src/render/svg_header_overlay.ts +93 -0
- package/treb-grid/src/render/svg_selection_block.ts +187 -0
- package/treb-grid/src/render/tile_renderer.ts +2122 -0
- package/treb-grid/src/types/annotation.ts +216 -0
- package/treb-grid/src/types/border_constants.ts +34 -0
- package/treb-grid/src/types/clipboard_data.ts +31 -0
- package/treb-grid/src/types/data_model.ts +334 -0
- package/treb-grid/src/types/drag_mask.ts +81 -0
- package/treb-grid/src/types/grid.ts +7743 -0
- package/treb-grid/src/types/grid_base.ts +3644 -0
- package/treb-grid/src/types/grid_command.ts +470 -0
- package/treb-grid/src/types/grid_events.ts +124 -0
- package/treb-grid/src/types/grid_options.ts +97 -0
- package/treb-grid/src/types/grid_selection.ts +60 -0
- package/treb-grid/src/types/named_range.ts +369 -0
- package/treb-grid/src/types/scale-control.ts +202 -0
- package/treb-grid/src/types/serialize_options.ts +72 -0
- package/treb-grid/src/types/set_range_options.ts +52 -0
- package/treb-grid/src/types/sheet.ts +3099 -0
- package/treb-grid/src/types/sheet_types.ts +95 -0
- package/treb-grid/src/types/tab_bar.ts +464 -0
- package/treb-grid/src/types/tile.ts +59 -0
- package/treb-grid/src/types/update_flags.ts +75 -0
- package/treb-grid/src/util/dom_utilities.ts +44 -0
- package/treb-grid/src/util/fontmetrics2.ts +179 -0
- package/treb-grid/src/util/ua.ts +104 -0
- package/treb-logo.svg +18 -0
- package/treb-parser/package.json +5 -0
- package/treb-parser/src/csv-parser.ts +122 -0
- package/treb-parser/src/index.ts +25 -0
- package/treb-parser/src/md-parser.ts +526 -0
- package/treb-parser/src/parser-types.ts +397 -0
- package/treb-parser/src/parser.test.ts +298 -0
- package/treb-parser/src/parser.ts +2673 -0
- package/treb-utils/package.json +5 -0
- package/treb-utils/src/dispatch.ts +57 -0
- package/treb-utils/src/event_source.ts +147 -0
- package/treb-utils/src/ievent_source.ts +33 -0
- package/treb-utils/src/index.ts +31 -0
- package/treb-utils/src/measurement.ts +174 -0
- package/treb-utils/src/resizable.ts +160 -0
- package/treb-utils/src/scale.ts +137 -0
- package/treb-utils/src/serialize_html.ts +124 -0
- package/treb-utils/src/template.ts +70 -0
- package/treb-utils/src/validate_uri.ts +61 -0
- package/tsconfig.json +10 -0
- package/tsproject.json +30 -0
- package/util/license-plugin-esbuild.js +86 -0
- package/util/list-css-vars.sh +46 -0
- package/README-esm.md +0 -37
- package/treb-bundle.css +0 -2
- 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
|
+
|