oakscriptjs 0.8.2 → 0.9.0

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 (546) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +31 -9
  3. package/dist/cjs/array/index.d.ts +701 -0
  4. package/dist/cjs/array/index.d.ts.map +1 -0
  5. package/dist/cjs/array/index.js +392 -0
  6. package/dist/cjs/array/index.js.map +7 -0
  7. package/dist/cjs/box/index.d.ts +444 -0
  8. package/dist/cjs/box/index.d.ts.map +1 -0
  9. package/dist/cjs/box/index.js +246 -0
  10. package/dist/cjs/box/index.js.map +7 -0
  11. package/dist/cjs/callsite/index.d.ts +61 -0
  12. package/dist/cjs/callsite/index.d.ts.map +1 -0
  13. package/dist/cjs/callsite/index.js +65 -0
  14. package/dist/cjs/callsite/index.js.map +7 -0
  15. package/dist/cjs/chartpoint/index.d.ts +90 -0
  16. package/dist/cjs/chartpoint/index.d.ts.map +1 -0
  17. package/dist/cjs/chartpoint/index.js +56 -0
  18. package/dist/cjs/chartpoint/index.js.map +7 -0
  19. package/dist/cjs/color/index.d.ts +285 -0
  20. package/dist/cjs/color/index.d.ts.map +1 -0
  21. package/dist/cjs/color/index.js +143 -0
  22. package/dist/cjs/color/index.js.map +7 -0
  23. package/dist/cjs/compare/index.d.ts +26 -0
  24. package/dist/cjs/compare/index.d.ts.map +1 -0
  25. package/dist/cjs/compare/index.js +50 -0
  26. package/dist/cjs/compare/index.js.map +7 -0
  27. package/dist/cjs/drawing/registry.d.ts +42 -0
  28. package/dist/cjs/drawing/registry.d.ts.map +1 -0
  29. package/dist/cjs/drawing/registry.js +87 -0
  30. package/dist/cjs/drawing/registry.js.map +7 -0
  31. package/dist/cjs/index.d.ts +85 -0
  32. package/dist/cjs/index.d.ts.map +1 -0
  33. package/dist/cjs/index.js +184 -0
  34. package/dist/cjs/index.js.map +7 -0
  35. package/dist/cjs/indicator.d.ts +117 -0
  36. package/dist/cjs/indicator.d.ts.map +1 -0
  37. package/dist/cjs/indicator.js +74 -0
  38. package/dist/cjs/indicator.js.map +7 -0
  39. package/dist/cjs/input.d.ts +196 -0
  40. package/dist/cjs/input.d.ts.map +1 -0
  41. package/dist/cjs/input.js +197 -0
  42. package/dist/cjs/input.js.map +7 -0
  43. package/dist/cjs/label/index.d.ts +303 -0
  44. package/dist/cjs/label/index.d.ts.map +1 -0
  45. package/dist/cjs/label/index.js +190 -0
  46. package/dist/cjs/label/index.js.map +7 -0
  47. package/dist/cjs/lib/index.d.ts +8 -0
  48. package/dist/cjs/lib/index.d.ts.map +1 -0
  49. package/dist/cjs/lib/index.js +19 -0
  50. package/dist/cjs/lib/index.js.map +7 -0
  51. package/dist/{lib → cjs/lib}/zigzag/index.d.ts +4 -1
  52. package/dist/cjs/lib/zigzag/index.d.ts.map +1 -0
  53. package/dist/cjs/lib/zigzag/index.js +27 -0
  54. package/dist/cjs/lib/zigzag/index.js.map +7 -0
  55. package/dist/cjs/lib/zigzag/zigzag.d.ts +100 -0
  56. package/dist/cjs/lib/zigzag/zigzag.d.ts.map +1 -0
  57. package/dist/cjs/lib/zigzag/zigzag.js +207 -0
  58. package/dist/cjs/lib/zigzag/zigzag.js.map +7 -0
  59. package/dist/cjs/line/index.d.ts +342 -0
  60. package/dist/cjs/line/index.d.ts.map +1 -0
  61. package/dist/cjs/line/index.js +193 -0
  62. package/dist/cjs/line/index.js.map +7 -0
  63. package/dist/cjs/linefill/index.d.ts +124 -0
  64. package/dist/cjs/linefill/index.d.ts.map +1 -0
  65. package/dist/cjs/linefill/index.js +56 -0
  66. package/dist/cjs/linefill/index.js.map +7 -0
  67. package/dist/cjs/map/index.d.ts +69 -0
  68. package/dist/cjs/map/index.d.ts.map +1 -0
  69. package/dist/cjs/map/index.js +80 -0
  70. package/dist/cjs/map/index.js.map +7 -0
  71. package/dist/cjs/math/index.d.ts +560 -0
  72. package/dist/cjs/math/index.d.ts.map +1 -0
  73. package/dist/cjs/math/index.js +441 -0
  74. package/dist/cjs/math/index.js.map +7 -0
  75. package/dist/cjs/matrix/index.d.ts +1231 -0
  76. package/dist/cjs/matrix/index.d.ts.map +1 -0
  77. package/dist/cjs/matrix/index.js +1200 -0
  78. package/dist/cjs/matrix/index.js.map +7 -0
  79. package/dist/cjs/package.json +1 -0
  80. package/dist/cjs/plot.d.ts +76 -0
  81. package/dist/cjs/plot.d.ts.map +1 -0
  82. package/dist/cjs/plot.js +51 -0
  83. package/dist/cjs/plot.js.map +7 -0
  84. package/dist/cjs/polyline/index.d.ts +115 -0
  85. package/dist/cjs/polyline/index.d.ts.map +1 -0
  86. package/dist/cjs/polyline/index.js +76 -0
  87. package/dist/cjs/polyline/index.js.map +7 -0
  88. package/dist/cjs/runtime/adapters/LightweightChartsAdapter.d.ts +86 -0
  89. package/dist/cjs/runtime/adapters/LightweightChartsAdapter.d.ts.map +1 -0
  90. package/dist/cjs/runtime/adapters/LightweightChartsAdapter.js +141 -0
  91. package/dist/cjs/runtime/adapters/LightweightChartsAdapter.js.map +7 -0
  92. package/dist/cjs/runtime/adapters/SimpleInputAdapter.d.ts +59 -0
  93. package/dist/cjs/runtime/adapters/SimpleInputAdapter.d.ts.map +1 -0
  94. package/dist/cjs/runtime/adapters/SimpleInputAdapter.js +117 -0
  95. package/dist/cjs/runtime/adapters/SimpleInputAdapter.js.map +7 -0
  96. package/dist/{runtime → cjs/runtime}/index.d.ts +12 -5
  97. package/dist/cjs/runtime/index.d.ts.map +1 -0
  98. package/dist/cjs/runtime/index.js +49 -0
  99. package/dist/cjs/runtime/index.js.map +7 -0
  100. package/dist/cjs/runtime/inputs.d.ts +91 -0
  101. package/dist/cjs/runtime/inputs.d.ts.map +1 -0
  102. package/dist/cjs/runtime/inputs.js +262 -0
  103. package/dist/cjs/runtime/inputs.js.map +7 -0
  104. package/dist/cjs/runtime/runtime.d.ts +70 -0
  105. package/dist/cjs/runtime/runtime.d.ts.map +1 -0
  106. package/dist/cjs/runtime/runtime.js +148 -0
  107. package/dist/cjs/runtime/runtime.js.map +7 -0
  108. package/dist/cjs/runtime/series.d.ts +362 -0
  109. package/dist/cjs/runtime/series.d.ts.map +1 -0
  110. package/dist/cjs/runtime/series.js +560 -0
  111. package/dist/cjs/runtime/series.js.map +7 -0
  112. package/dist/cjs/runtime/types.d.ts +282 -0
  113. package/dist/cjs/runtime/types.d.ts.map +1 -0
  114. package/dist/cjs/runtime/types.js +17 -0
  115. package/dist/cjs/runtime/types.js.map +7 -0
  116. package/dist/cjs/script/index.d.ts +987 -0
  117. package/dist/cjs/script/index.d.ts.map +1 -0
  118. package/dist/cjs/script/index.js +1169 -0
  119. package/dist/cjs/script/index.js.map +7 -0
  120. package/dist/cjs/security/resample.d.ts +63 -0
  121. package/dist/cjs/security/resample.d.ts.map +1 -0
  122. package/dist/cjs/security/resample.js +84 -0
  123. package/dist/cjs/security/resample.js.map +7 -0
  124. package/dist/cjs/session/bars.d.ts +80 -0
  125. package/dist/cjs/session/bars.d.ts.map +1 -0
  126. package/dist/cjs/session/bars.js +219 -0
  127. package/dist/cjs/session/bars.js.map +7 -0
  128. package/dist/cjs/session/calendar.d.ts +70 -0
  129. package/dist/cjs/session/calendar.d.ts.map +1 -0
  130. package/dist/cjs/session/calendar.js +164 -0
  131. package/dist/cjs/session/calendar.js.map +7 -0
  132. package/dist/cjs/str/dateformat.d.ts +15 -0
  133. package/dist/cjs/str/dateformat.d.ts.map +1 -0
  134. package/dist/cjs/str/dateformat.js +149 -0
  135. package/dist/cjs/str/dateformat.js.map +7 -0
  136. package/dist/cjs/str/index.d.ts +459 -0
  137. package/dist/cjs/str/index.d.ts.map +1 -0
  138. package/dist/cjs/str/index.js +143 -0
  139. package/dist/cjs/str/index.js.map +7 -0
  140. package/dist/cjs/str/messageformat.d.ts +14 -0
  141. package/dist/cjs/str/messageformat.d.ts.map +1 -0
  142. package/dist/cjs/str/messageformat.js +114 -0
  143. package/dist/cjs/str/messageformat.js.map +7 -0
  144. package/dist/cjs/str/numberformat.d.ts +19 -0
  145. package/dist/cjs/str/numberformat.d.ts.map +1 -0
  146. package/dist/cjs/str/numberformat.js +170 -0
  147. package/dist/cjs/str/numberformat.js.map +7 -0
  148. package/dist/{strategy → cjs/strategy}/index.d.ts +50 -0
  149. package/dist/cjs/strategy/index.d.ts.map +1 -0
  150. package/dist/cjs/strategy/index.js +92 -0
  151. package/dist/cjs/strategy/index.js.map +7 -0
  152. package/dist/cjs/ta/index.d.ts +1397 -0
  153. package/dist/cjs/ta/index.d.ts.map +1 -0
  154. package/dist/cjs/ta/index.js +1715 -0
  155. package/dist/cjs/ta/index.js.map +7 -0
  156. package/dist/cjs/ta/running-sum.d.ts +30 -0
  157. package/dist/cjs/ta/running-sum.d.ts.map +1 -0
  158. package/dist/cjs/ta/running-sum.js +99 -0
  159. package/dist/cjs/ta/running-sum.js.map +7 -0
  160. package/dist/cjs/ta-series.d.ts +558 -0
  161. package/dist/cjs/ta-series.d.ts.map +1 -0
  162. package/dist/cjs/ta-series.js +606 -0
  163. package/dist/cjs/ta-series.js.map +7 -0
  164. package/dist/cjs/text/index.d.ts +14 -0
  165. package/dist/cjs/text/index.d.ts.map +1 -0
  166. package/dist/cjs/text/index.js +29 -0
  167. package/dist/cjs/text/index.js.map +7 -0
  168. package/dist/cjs/time/datestring.d.ts +23 -0
  169. package/dist/cjs/time/datestring.d.ts.map +1 -0
  170. package/dist/cjs/time/datestring.js +106 -0
  171. package/dist/cjs/time/datestring.js.map +7 -0
  172. package/dist/cjs/time/index.d.ts +89 -0
  173. package/dist/cjs/time/index.d.ts.map +1 -0
  174. package/dist/cjs/time/index.js +85 -0
  175. package/dist/cjs/time/index.js.map +7 -0
  176. package/dist/cjs/time/session.d.ts +17 -0
  177. package/dist/cjs/time/session.d.ts.map +1 -0
  178. package/dist/cjs/time/session.js +65 -0
  179. package/dist/cjs/time/session.js.map +7 -0
  180. package/dist/cjs/time/timezone.d.ts +40 -0
  181. package/dist/cjs/time/timezone.d.ts.map +1 -0
  182. package/dist/cjs/time/timezone.js +125 -0
  183. package/dist/cjs/time/timezone.js.map +7 -0
  184. package/dist/cjs/timeframe/index.d.ts +73 -0
  185. package/dist/cjs/timeframe/index.d.ts.map +1 -0
  186. package/dist/cjs/timeframe/index.js +85 -0
  187. package/dist/cjs/timeframe/index.js.map +7 -0
  188. package/dist/cjs/types/index.d.ts +343 -0
  189. package/dist/cjs/types/index.d.ts.map +1 -0
  190. package/dist/cjs/types/index.js +32 -0
  191. package/dist/cjs/types/index.js.map +7 -0
  192. package/dist/cjs/types/metadata.d.ts +300 -0
  193. package/dist/cjs/types/metadata.d.ts.map +1 -0
  194. package/dist/cjs/types/metadata.js +17 -0
  195. package/dist/cjs/types/metadata.js.map +7 -0
  196. package/dist/cjs/utils/index.d.ts +167 -0
  197. package/dist/cjs/utils/index.d.ts.map +1 -0
  198. package/dist/cjs/utils/index.js +209 -0
  199. package/dist/cjs/utils/index.js.map +7 -0
  200. package/dist/esm/array/index.d.ts +701 -0
  201. package/dist/esm/array/index.d.ts.map +1 -0
  202. package/dist/esm/array/index.js +983 -0
  203. package/dist/esm/array/index.js.map +1 -0
  204. package/dist/esm/box/index.d.ts +444 -0
  205. package/dist/esm/box/index.d.ts.map +1 -0
  206. package/dist/esm/box/index.js +602 -0
  207. package/dist/esm/box/index.js.map +1 -0
  208. package/dist/esm/callsite/index.d.ts +61 -0
  209. package/dist/esm/callsite/index.d.ts.map +1 -0
  210. package/dist/esm/callsite/index.js +97 -0
  211. package/dist/esm/callsite/index.js.map +1 -0
  212. package/dist/esm/chartpoint/index.d.ts +90 -0
  213. package/dist/esm/chartpoint/index.d.ts.map +1 -0
  214. package/dist/esm/chartpoint/index.js +113 -0
  215. package/dist/esm/chartpoint/index.js.map +1 -0
  216. package/dist/esm/color/index.d.ts +285 -0
  217. package/dist/esm/color/index.d.ts.map +1 -0
  218. package/dist/esm/color/index.js +373 -0
  219. package/dist/esm/color/index.js.map +1 -0
  220. package/dist/esm/compare/index.d.ts +26 -0
  221. package/dist/esm/compare/index.d.ts.map +1 -0
  222. package/dist/esm/compare/index.js +39 -0
  223. package/dist/esm/compare/index.js.map +1 -0
  224. package/dist/esm/drawing/registry.d.ts +42 -0
  225. package/dist/esm/drawing/registry.d.ts.map +1 -0
  226. package/dist/esm/drawing/registry.js +89 -0
  227. package/dist/esm/drawing/registry.js.map +1 -0
  228. package/dist/esm/index.d.ts +85 -0
  229. package/dist/esm/index.d.ts.map +1 -0
  230. package/dist/esm/index.js +96 -0
  231. package/dist/esm/index.js.map +1 -0
  232. package/dist/esm/indicator.d.ts +117 -0
  233. package/dist/esm/indicator.d.ts.map +1 -0
  234. package/dist/esm/indicator.js +84 -0
  235. package/dist/esm/indicator.js.map +1 -0
  236. package/dist/esm/input.d.ts +196 -0
  237. package/dist/esm/input.d.ts.map +1 -0
  238. package/dist/esm/input.js +183 -0
  239. package/dist/esm/input.js.map +1 -0
  240. package/dist/esm/label/index.d.ts +303 -0
  241. package/dist/esm/label/index.d.ts.map +1 -0
  242. package/dist/esm/label/index.js +417 -0
  243. package/dist/esm/label/index.js.map +1 -0
  244. package/dist/esm/lib/index.d.ts +8 -0
  245. package/dist/esm/lib/index.d.ts.map +1 -0
  246. package/dist/esm/lib/index.js +8 -0
  247. package/dist/esm/lib/index.js.map +1 -0
  248. package/dist/esm/lib/zigzag/index.d.ts +5 -0
  249. package/dist/esm/lib/zigzag/index.d.ts.map +1 -0
  250. package/dist/esm/lib/zigzag/index.js +5 -0
  251. package/dist/esm/lib/zigzag/index.js.map +1 -0
  252. package/dist/esm/lib/zigzag/zigzag.d.ts +100 -0
  253. package/dist/esm/lib/zigzag/zigzag.d.ts.map +1 -0
  254. package/dist/esm/lib/zigzag/zigzag.js +229 -0
  255. package/dist/esm/lib/zigzag/zigzag.js.map +1 -0
  256. package/dist/esm/line/index.d.ts +342 -0
  257. package/dist/esm/line/index.d.ts.map +1 -0
  258. package/dist/esm/line/index.js +470 -0
  259. package/dist/esm/line/index.js.map +1 -0
  260. package/dist/esm/linefill/index.d.ts +124 -0
  261. package/dist/esm/linefill/index.d.ts.map +1 -0
  262. package/dist/esm/linefill/index.js +144 -0
  263. package/dist/esm/linefill/index.js.map +1 -0
  264. package/dist/esm/map/index.d.ts +69 -0
  265. package/dist/esm/map/index.d.ts.map +1 -0
  266. package/dist/esm/map/index.js +106 -0
  267. package/dist/esm/map/index.js.map +1 -0
  268. package/dist/esm/math/index.d.ts +560 -0
  269. package/dist/esm/math/index.d.ts.map +1 -0
  270. package/dist/esm/math/index.js +495 -0
  271. package/dist/esm/math/index.js.map +1 -0
  272. package/dist/esm/matrix/index.d.ts +1231 -0
  273. package/dist/esm/matrix/index.d.ts.map +1 -0
  274. package/dist/esm/matrix/index.js +2450 -0
  275. package/dist/esm/matrix/index.js.map +1 -0
  276. package/dist/esm/plot.d.ts +76 -0
  277. package/dist/esm/plot.d.ts.map +1 -0
  278. package/dist/esm/plot.js +63 -0
  279. package/dist/esm/plot.js.map +1 -0
  280. package/dist/esm/polyline/index.d.ts +115 -0
  281. package/dist/esm/polyline/index.d.ts.map +1 -0
  282. package/dist/esm/polyline/index.js +157 -0
  283. package/dist/esm/polyline/index.js.map +1 -0
  284. package/dist/esm/runtime/adapters/LightweightChartsAdapter.d.ts +86 -0
  285. package/dist/esm/runtime/adapters/LightweightChartsAdapter.d.ts.map +1 -0
  286. package/dist/esm/runtime/adapters/LightweightChartsAdapter.js +140 -0
  287. package/dist/esm/runtime/adapters/LightweightChartsAdapter.js.map +1 -0
  288. package/dist/esm/runtime/adapters/SimpleInputAdapter.d.ts +59 -0
  289. package/dist/esm/runtime/adapters/SimpleInputAdapter.d.ts.map +1 -0
  290. package/dist/esm/runtime/adapters/SimpleInputAdapter.js +115 -0
  291. package/dist/esm/runtime/adapters/SimpleInputAdapter.js.map +1 -0
  292. package/dist/esm/runtime/index.d.ts +13 -0
  293. package/dist/esm/runtime/index.d.ts.map +1 -0
  294. package/dist/esm/runtime/index.js +14 -0
  295. package/dist/esm/runtime/index.js.map +1 -0
  296. package/dist/esm/runtime/inputs.d.ts +91 -0
  297. package/dist/esm/runtime/inputs.d.ts.map +1 -0
  298. package/dist/esm/runtime/inputs.js +334 -0
  299. package/dist/esm/runtime/inputs.js.map +1 -0
  300. package/dist/esm/runtime/runtime.d.ts +70 -0
  301. package/dist/esm/runtime/runtime.d.ts.map +1 -0
  302. package/dist/esm/runtime/runtime.js +193 -0
  303. package/dist/esm/runtime/runtime.js.map +1 -0
  304. package/dist/esm/runtime/series.d.ts +362 -0
  305. package/dist/esm/runtime/series.d.ts.map +1 -0
  306. package/dist/esm/runtime/series.js +583 -0
  307. package/dist/esm/runtime/series.js.map +1 -0
  308. package/dist/esm/runtime/types.d.ts +282 -0
  309. package/dist/esm/runtime/types.d.ts.map +1 -0
  310. package/dist/esm/runtime/types.js +7 -0
  311. package/dist/esm/runtime/types.js.map +1 -0
  312. package/dist/esm/script/index.d.ts +987 -0
  313. package/dist/esm/script/index.d.ts.map +1 -0
  314. package/dist/esm/script/index.js +1289 -0
  315. package/dist/esm/script/index.js.map +1 -0
  316. package/dist/esm/security/resample.d.ts +63 -0
  317. package/dist/esm/security/resample.d.ts.map +1 -0
  318. package/dist/esm/security/resample.js +110 -0
  319. package/dist/esm/security/resample.js.map +1 -0
  320. package/dist/esm/session/bars.d.ts +80 -0
  321. package/dist/esm/session/bars.d.ts.map +1 -0
  322. package/dist/esm/session/bars.js +232 -0
  323. package/dist/esm/session/bars.js.map +1 -0
  324. package/dist/esm/session/calendar.d.ts +70 -0
  325. package/dist/esm/session/calendar.d.ts.map +1 -0
  326. package/dist/esm/session/calendar.js +172 -0
  327. package/dist/esm/session/calendar.js.map +1 -0
  328. package/dist/esm/str/dateformat.d.ts +15 -0
  329. package/dist/esm/str/dateformat.d.ts.map +1 -0
  330. package/dist/esm/str/dateformat.js +136 -0
  331. package/dist/esm/str/dateformat.js.map +1 -0
  332. package/dist/esm/str/index.d.ts +459 -0
  333. package/dist/esm/str/index.d.ts.map +1 -0
  334. package/dist/esm/str/index.js +540 -0
  335. package/dist/esm/str/index.js.map +1 -0
  336. package/dist/esm/str/messageformat.d.ts +14 -0
  337. package/dist/esm/str/messageformat.d.ts.map +1 -0
  338. package/dist/esm/str/messageformat.js +111 -0
  339. package/dist/esm/str/messageformat.js.map +1 -0
  340. package/dist/esm/str/numberformat.d.ts +19 -0
  341. package/dist/esm/str/numberformat.d.ts.map +1 -0
  342. package/dist/esm/str/numberformat.js +189 -0
  343. package/dist/esm/str/numberformat.js.map +1 -0
  344. package/dist/esm/strategy/index.d.ts +245 -0
  345. package/dist/esm/strategy/index.d.ts.map +1 -0
  346. package/dist/esm/strategy/index.js +84 -0
  347. package/dist/esm/strategy/index.js.map +1 -0
  348. package/dist/esm/ta/index.d.ts +1397 -0
  349. package/dist/esm/ta/index.d.ts.map +1 -0
  350. package/dist/esm/ta/index.js +3227 -0
  351. package/dist/esm/ta/index.js.map +1 -0
  352. package/dist/esm/ta/running-sum.d.ts +30 -0
  353. package/dist/esm/ta/running-sum.d.ts.map +1 -0
  354. package/dist/esm/ta/running-sum.js +113 -0
  355. package/dist/esm/ta/running-sum.js.map +1 -0
  356. package/dist/esm/ta-series.d.ts +558 -0
  357. package/dist/esm/ta-series.d.ts.map +1 -0
  358. package/dist/esm/ta-series.js +910 -0
  359. package/dist/esm/ta-series.js.map +1 -0
  360. package/dist/esm/text/index.d.ts +14 -0
  361. package/dist/esm/text/index.d.ts.map +1 -0
  362. package/dist/esm/text/index.js +14 -0
  363. package/dist/esm/text/index.js.map +1 -0
  364. package/dist/esm/time/datestring.d.ts +23 -0
  365. package/dist/esm/time/datestring.d.ts.map +1 -0
  366. package/dist/esm/time/datestring.js +94 -0
  367. package/dist/esm/time/datestring.js.map +1 -0
  368. package/dist/esm/time/index.d.ts +89 -0
  369. package/dist/esm/time/index.d.ts.map +1 -0
  370. package/dist/esm/time/index.js +108 -0
  371. package/dist/esm/time/index.js.map +1 -0
  372. package/dist/esm/time/session.d.ts +17 -0
  373. package/dist/esm/time/session.d.ts.map +1 -0
  374. package/dist/esm/time/session.js +69 -0
  375. package/dist/esm/time/session.js.map +1 -0
  376. package/dist/esm/time/timezone.d.ts +40 -0
  377. package/dist/esm/time/timezone.d.ts.map +1 -0
  378. package/dist/esm/time/timezone.js +144 -0
  379. package/dist/esm/time/timezone.js.map +1 -0
  380. package/dist/esm/timeframe/index.d.ts +73 -0
  381. package/dist/esm/timeframe/index.d.ts.map +1 -0
  382. package/dist/esm/timeframe/index.js +131 -0
  383. package/dist/esm/timeframe/index.js.map +1 -0
  384. package/dist/esm/types/index.d.ts +343 -0
  385. package/dist/esm/types/index.d.ts.map +1 -0
  386. package/dist/esm/types/index.js +17 -0
  387. package/dist/esm/types/index.js.map +1 -0
  388. package/dist/esm/types/metadata.d.ts +300 -0
  389. package/dist/esm/types/metadata.d.ts.map +1 -0
  390. package/dist/esm/types/metadata.js +7 -0
  391. package/dist/esm/types/metadata.js.map +1 -0
  392. package/dist/esm/utils/index.d.ts +167 -0
  393. package/dist/esm/utils/index.d.ts.map +1 -0
  394. package/dist/esm/utils/index.js +295 -0
  395. package/dist/esm/utils/index.js.map +1 -0
  396. package/package.json +53 -23
  397. package/src/array/index.ts +1056 -0
  398. package/src/box/index.ts +680 -0
  399. package/src/callsite/index.ts +104 -0
  400. package/src/chartpoint/index.ts +126 -0
  401. package/src/color/index.ts +411 -0
  402. package/src/compare/index.ts +46 -0
  403. package/src/drawing/registry.ts +106 -0
  404. package/src/index.ts +201 -0
  405. package/src/indicator.ts +185 -0
  406. package/src/input.ts +280 -0
  407. package/src/label/index.ts +490 -0
  408. package/src/lib/index.ts +8 -0
  409. package/src/lib/zigzag/index.ts +13 -0
  410. package/src/lib/zigzag/zigzag.ts +318 -0
  411. package/src/line/index.ts +530 -0
  412. package/src/linefill/index.ts +152 -0
  413. package/src/map/index.ts +115 -0
  414. package/src/math/index.ts +1071 -0
  415. package/src/matrix/index.ts +2697 -0
  416. package/src/plot.ts +121 -0
  417. package/src/polyline/index.ts +184 -0
  418. package/src/runtime/adapters/LightweightChartsAdapter.ts +201 -0
  419. package/src/runtime/adapters/SimpleInputAdapter.ts +132 -0
  420. package/src/runtime/index.ts +52 -0
  421. package/src/runtime/inputs.ts +377 -0
  422. package/src/runtime/runtime.ts +241 -0
  423. package/src/runtime/series.ts +644 -0
  424. package/src/runtime/types.ts +292 -0
  425. package/src/script/index.ts +1865 -0
  426. package/src/security/resample.ts +119 -0
  427. package/src/session/bars.ts +262 -0
  428. package/src/session/calendar.ts +199 -0
  429. package/src/str/dateformat.ts +104 -0
  430. package/src/str/index.ts +557 -0
  431. package/src/str/messageformat.ts +109 -0
  432. package/src/str/numberformat.ts +197 -0
  433. package/src/strategy/index.ts +281 -0
  434. package/src/ta/index.ts +3580 -0
  435. package/src/ta/running-sum.ts +117 -0
  436. package/src/ta-series.ts +1036 -0
  437. package/src/text/index.ts +14 -0
  438. package/src/time/datestring.ts +96 -0
  439. package/src/time/index.ts +161 -0
  440. package/src/time/session.ts +79 -0
  441. package/src/time/timezone.ts +180 -0
  442. package/src/timeframe/index.ts +144 -0
  443. package/src/types/index.ts +398 -0
  444. package/src/types/metadata.ts +334 -0
  445. package/src/utils/index.ts +334 -0
  446. package/dist/array/index.d.ts +0 -57
  447. package/dist/array/index.d.ts.map +0 -1
  448. package/dist/box/index.d.ts +0 -37
  449. package/dist/box/index.d.ts.map +0 -1
  450. package/dist/callsite/index.d.ts +0 -7
  451. package/dist/callsite/index.d.ts.map +0 -1
  452. package/dist/chartpoint/index.d.ts +0 -8
  453. package/dist/chartpoint/index.d.ts.map +0 -1
  454. package/dist/color/index.d.ts +0 -28
  455. package/dist/color/index.d.ts.map +0 -1
  456. package/dist/compare/index.d.ts +0 -8
  457. package/dist/compare/index.d.ts.map +0 -1
  458. package/dist/drawing/registry.d.ts +0 -19
  459. package/dist/drawing/registry.d.ts.map +0 -1
  460. package/dist/index.cjs +0 -7981
  461. package/dist/index.d.ts +0 -64
  462. package/dist/index.d.ts.map +0 -1
  463. package/dist/index.mjs +0 -7964
  464. package/dist/indicator.d.ts +0 -42
  465. package/dist/indicator.d.ts.map +0 -1
  466. package/dist/input.d.ts +0 -47
  467. package/dist/input.d.ts.map +0 -1
  468. package/dist/label/index.d.ts +0 -30
  469. package/dist/label/index.d.ts.map +0 -1
  470. package/dist/lib/index.d.ts +0 -2
  471. package/dist/lib/index.d.ts.map +0 -1
  472. package/dist/lib/zigzag/index.d.ts.map +0 -1
  473. package/dist/lib/zigzag/zigzag.d.ts +0 -47
  474. package/dist/lib/zigzag/zigzag.d.ts.map +0 -1
  475. package/dist/line/index.d.ts +0 -30
  476. package/dist/line/index.d.ts.map +0 -1
  477. package/dist/linefill/index.d.ts +0 -10
  478. package/dist/linefill/index.d.ts.map +0 -1
  479. package/dist/map/index.d.ts +0 -14
  480. package/dist/map/index.d.ts.map +0 -1
  481. package/dist/math/index.d.ts +0 -53
  482. package/dist/math/index.d.ts.map +0 -1
  483. package/dist/matrix/index.d.ts +0 -52
  484. package/dist/matrix/index.d.ts.map +0 -1
  485. package/dist/plot.d.ts +0 -20
  486. package/dist/plot.d.ts.map +0 -1
  487. package/dist/polyline/index.d.ts +0 -11
  488. package/dist/polyline/index.d.ts.map +0 -1
  489. package/dist/runtime/adapters/LightweightChartsAdapter.d.ts +0 -15
  490. package/dist/runtime/adapters/LightweightChartsAdapter.d.ts.map +0 -1
  491. package/dist/runtime/adapters/SimpleInputAdapter.d.ts +0 -16
  492. package/dist/runtime/adapters/SimpleInputAdapter.d.ts.map +0 -1
  493. package/dist/runtime/index.cjs +0 -600
  494. package/dist/runtime/index.d.ts.map +0 -1
  495. package/dist/runtime/index.mjs +0 -577
  496. package/dist/runtime/inputs.d.ts +0 -13
  497. package/dist/runtime/inputs.d.ts.map +0 -1
  498. package/dist/runtime/runtime.d.ts +0 -16
  499. package/dist/runtime/runtime.d.ts.map +0 -1
  500. package/dist/runtime/series.d.ts +0 -60
  501. package/dist/runtime/series.d.ts.map +0 -1
  502. package/dist/runtime/types.d.ts +0 -126
  503. package/dist/runtime/types.d.ts.map +0 -1
  504. package/dist/script/index.cjs +0 -6377
  505. package/dist/script/index.d.ts +0 -713
  506. package/dist/script/index.d.ts.map +0 -1
  507. package/dist/script/index.mjs +0 -6360
  508. package/dist/security/resample.d.ts +0 -13
  509. package/dist/security/resample.d.ts.map +0 -1
  510. package/dist/session/bars.d.ts +0 -34
  511. package/dist/session/bars.d.ts.map +0 -1
  512. package/dist/session/calendar.d.ts +0 -31
  513. package/dist/session/calendar.d.ts.map +0 -1
  514. package/dist/str/dateformat.d.ts +0 -2
  515. package/dist/str/dateformat.d.ts.map +0 -1
  516. package/dist/str/index.d.ts +0 -24
  517. package/dist/str/index.d.ts.map +0 -1
  518. package/dist/str/messageformat.d.ts +0 -2
  519. package/dist/str/messageformat.d.ts.map +0 -1
  520. package/dist/str/numberformat.d.ts +0 -3
  521. package/dist/str/numberformat.d.ts.map +0 -1
  522. package/dist/strategy/index.d.ts.map +0 -1
  523. package/dist/ta/index.d.ts +0 -72
  524. package/dist/ta/index.d.ts.map +0 -1
  525. package/dist/ta/running-sum.d.ts +0 -3
  526. package/dist/ta/running-sum.d.ts.map +0 -1
  527. package/dist/ta-series.d.ts +0 -143
  528. package/dist/ta-series.d.ts.map +0 -1
  529. package/dist/text/index.d.ts +0 -4
  530. package/dist/text/index.d.ts.map +0 -1
  531. package/dist/time/datestring.d.ts +0 -2
  532. package/dist/time/datestring.d.ts.map +0 -1
  533. package/dist/time/index.d.ts +0 -15
  534. package/dist/time/index.d.ts.map +0 -1
  535. package/dist/time/session.d.ts +0 -2
  536. package/dist/time/session.d.ts.map +0 -1
  537. package/dist/time/timezone.d.ts +0 -13
  538. package/dist/time/timezone.d.ts.map +0 -1
  539. package/dist/timeframe/index.d.ts +0 -17
  540. package/dist/timeframe/index.d.ts.map +0 -1
  541. package/dist/types/index.d.ts +0 -181
  542. package/dist/types/index.d.ts.map +0 -1
  543. package/dist/types/metadata.d.ts +0 -132
  544. package/dist/types/metadata.d.ts.map +0 -1
  545. package/dist/utils/index.d.ts +0 -26
  546. package/dist/utils/index.d.ts.map +0 -1
@@ -0,0 +1,2450 @@
1
+ /**
2
+ * Matrix namespace
3
+ * Mirrors PineScript's matrix.* functions
4
+ */
5
+ /**
6
+ * Creates a new matrix
7
+ *
8
+ * @param rows - Number of rows
9
+ * @param columns - Number of columns
10
+ * @param initial_value - Initial value for all elements
11
+ * @returns A new matrix object
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * // Create a 2x3 matrix filled with zeros
16
+ * const m = matrix.new_matrix(2, 3, 0);
17
+ *
18
+ * // Create a 3x3 identity-like matrix
19
+ * const m2 = matrix.new_matrix(3, 3, 1);
20
+ * ```
21
+ */
22
+ export function new_matrix(rows, columns, initial_value) {
23
+ const data = [];
24
+ for (let i = 0; i < rows; i++) {
25
+ const row = [];
26
+ for (let j = 0; j < columns; j++) {
27
+ row.push(initial_value);
28
+ }
29
+ data.push(row);
30
+ }
31
+ return { rows, columns, data };
32
+ }
33
+ /**
34
+ * Get element at position
35
+ *
36
+ * The function returns the element with the specified index of the matrix.
37
+ *
38
+ * @param id - A matrix object
39
+ * @param row - Index of the required row
40
+ * @param column - Index of the required column
41
+ * @returns The value of the element at the row and column index
42
+ *
43
+ * @remarks
44
+ * Indexing of the rows and columns starts at zero.
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * // Create a 2x3 matrix with value 5
49
+ * const m = matrix.new_matrix(2, 3, 5);
50
+ *
51
+ * // Get element at row 0, column 0
52
+ * const x = matrix.get(m, 0, 0); // Returns: 5
53
+ * ```
54
+ */
55
+ export function get(id, row, column) {
56
+ if (row < 0 || row >= id.rows || column < 0 || column >= id.columns) {
57
+ throw new Error(`Matrix index out of bounds: [${row}, ${column}] for matrix of size [${id.rows}, ${id.columns}]`);
58
+ }
59
+ return id.data[row][column];
60
+ }
61
+ /**
62
+ * Set element at position
63
+ *
64
+ * The function assigns value to the element at the row and column of the matrix.
65
+ *
66
+ * @param id - A matrix object
67
+ * @param row - The row index of the element to be modified
68
+ * @param column - The column index of the element to be modified
69
+ * @param value - The new value to be set
70
+ *
71
+ * @remarks
72
+ * Indexing of the rows and columns starts at zero.
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * // Create a 2x3 matrix with value 4
77
+ * const m = matrix.new_matrix(2, 3, 4);
78
+ *
79
+ * // Replace value at row 0, column 1 with 3
80
+ * matrix.set(m, 0, 1, 3);
81
+ *
82
+ * // Now m[0][1] === 3
83
+ * ```
84
+ */
85
+ export function set(id, row, column, value) {
86
+ if (row < 0 || row >= id.rows || column < 0 || column >= id.columns) {
87
+ throw new Error(`Matrix index out of bounds: [${row}, ${column}] for matrix of size [${id.rows}, ${id.columns}]`);
88
+ }
89
+ id.data[row][column] = value;
90
+ }
91
+ /**
92
+ * Get number of rows
93
+ *
94
+ * The function returns the number of rows in the matrix.
95
+ *
96
+ * @param id - A matrix object
97
+ * @returns The number of rows in the matrix
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * // Create a 2x6 matrix
102
+ * const m = matrix.new_matrix(2, 6, 0);
103
+ *
104
+ * // Get the quantity of rows
105
+ * const x = matrix.rows(m); // Returns: 2
106
+ * ```
107
+ */
108
+ export function rows(id) {
109
+ return id.rows;
110
+ }
111
+ /**
112
+ * Get number of columns
113
+ *
114
+ * The function returns the number of columns in the matrix.
115
+ *
116
+ * @param id - A matrix object
117
+ * @returns The number of columns in the matrix
118
+ *
119
+ * @example
120
+ * ```typescript
121
+ * // Create a 2x6 matrix
122
+ * const m = matrix.new_matrix(2, 6, 0);
123
+ *
124
+ * // Get the quantity of columns
125
+ * const x = matrix.columns(m); // Returns: 6
126
+ * ```
127
+ */
128
+ export function columns(id) {
129
+ return id.columns;
130
+ }
131
+ /**
132
+ * Get total number of elements
133
+ *
134
+ * The function returns the total number of all matrix elements.
135
+ *
136
+ * @param id - A matrix object
137
+ * @returns The total number of elements (rows * columns)
138
+ *
139
+ * @example
140
+ * ```typescript
141
+ * // Create a 3x4 matrix
142
+ * const m = matrix.new_matrix(3, 4, 0);
143
+ *
144
+ * // Get total element count
145
+ * const count = matrix.elements_count(m); // Returns: 12
146
+ * ```
147
+ */
148
+ export function elements_count(id) {
149
+ return id.rows * id.columns;
150
+ }
151
+ /**
152
+ * Get row as array
153
+ *
154
+ * The function creates a one-dimensional array from the elements of a matrix row.
155
+ *
156
+ * @param id - A matrix object
157
+ * @param row_index - Index of the required row
158
+ * @returns An array containing the values of the specified row
159
+ *
160
+ * @remarks
161
+ * Indexing of rows starts at 0.
162
+ * Returns a copy of the row data.
163
+ *
164
+ * @example
165
+ * ```typescript
166
+ * // Create a 2x3 matrix
167
+ * const m = matrix.new_matrix(2, 3, 5);
168
+ * matrix.set(m, 0, 0, 1);
169
+ * matrix.set(m, 0, 1, 2);
170
+ * matrix.set(m, 0, 2, 3);
171
+ *
172
+ * // Get the first row as an array
173
+ * const a = matrix.row(m, 0); // Returns: [1, 2, 3]
174
+ * ```
175
+ */
176
+ export function row(id, row_index) {
177
+ if (row_index < 0 || row_index >= id.rows) {
178
+ throw new Error(`Row index out of bounds: ${row_index} for matrix with ${id.rows} rows`);
179
+ }
180
+ return [...id.data[row_index]];
181
+ }
182
+ /**
183
+ * Get column as array
184
+ *
185
+ * The function creates a one-dimensional array from the elements of a matrix column.
186
+ *
187
+ * @param id - A matrix object
188
+ * @param column_index - Index of the required column
189
+ * @returns An array containing the values of the specified column
190
+ *
191
+ * @remarks
192
+ * Indexing of columns starts at 0.
193
+ * Returns a copy of the column data.
194
+ *
195
+ * @example
196
+ * ```typescript
197
+ * // Create a 3x2 matrix
198
+ * const m = matrix.new_matrix(3, 2, 0);
199
+ * matrix.set(m, 0, 0, 1);
200
+ * matrix.set(m, 1, 0, 2);
201
+ * matrix.set(m, 2, 0, 3);
202
+ *
203
+ * // Get the first column as an array
204
+ * const a = matrix.col(m, 0); // Returns: [1, 2, 3]
205
+ * ```
206
+ */
207
+ export function col(id, column_index) {
208
+ if (column_index < 0 || column_index >= id.columns) {
209
+ throw new Error(`Column index out of bounds: ${column_index} for matrix with ${id.columns} columns`);
210
+ }
211
+ return id.data.map(r => r[column_index]);
212
+ }
213
+ /**
214
+ * Create a deep copy of a matrix
215
+ *
216
+ * The function creates a new matrix which is a copy of the original.
217
+ *
218
+ * @param id - A matrix object to copy
219
+ * @returns A new matrix object that is a deep copy of the original
220
+ *
221
+ * @remarks
222
+ * Unlike a simple assignment operation which would only copy the reference,
223
+ * this function creates an actual copy of the matrix data.
224
+ *
225
+ * @example
226
+ * ```typescript
227
+ * // Create a 2x3 matrix with value 1
228
+ * const m1 = matrix.new_matrix(2, 3, 1);
229
+ *
230
+ * // Copy the matrix
231
+ * const m2 = matrix.copy(m1);
232
+ *
233
+ * // Modifying m2 will not affect m1
234
+ * matrix.set(m2, 0, 0, 99);
235
+ * // m1[0][0] is still 1
236
+ * // m2[0][0] is now 99
237
+ * ```
238
+ */
239
+ export function copy(id) {
240
+ const newData = id.data.map(r => [...r]);
241
+ return {
242
+ rows: id.rows,
243
+ columns: id.columns,
244
+ data: newData
245
+ };
246
+ }
247
+ /**
248
+ * Fill matrix with value
249
+ *
250
+ * The function fills a rectangular area of the matrix defined by the indices
251
+ * from_row to to_row (not including it) and from_column to to_column (not including it)
252
+ * with the specified value.
253
+ *
254
+ * @param id - A matrix object
255
+ * @param value - The value to fill with
256
+ * @param from_row - Row index from which the fill will begin (inclusive). Default: 0
257
+ * @param to_row - Row index where the fill will end (not inclusive). Default: matrix.rows
258
+ * @param from_column - Column index from which the fill will begin (inclusive). Default: 0
259
+ * @param to_column - Column index where the fill will end (not inclusive). Default: matrix.columns
260
+ *
261
+ * @example
262
+ * ```typescript
263
+ * // Create a 4x5 matrix with value 0
264
+ * const m = matrix.new_matrix(4, 5, 0);
265
+ *
266
+ * // Fill rows 0-1 and columns 1-2 with value 9
267
+ * matrix.fill(m, 9, 0, 2, 1, 3);
268
+ *
269
+ * // Result: positions [0,1], [0,2], [1,1], [1,2] are now 9
270
+ * ```
271
+ */
272
+ export function fill(id, value, from_row = 0, to_row, from_column = 0, to_column) {
273
+ const endRow = to_row ?? id.rows;
274
+ const endCol = to_column ?? id.columns;
275
+ for (let i = from_row; i < endRow; i++) {
276
+ for (let j = from_column; j < endCol; j++) {
277
+ id.data[i][j] = value;
278
+ }
279
+ }
280
+ }
281
+ /**
282
+ * Test if matrix is square
283
+ *
284
+ * The function determines if the matrix is square (it has the same number of rows and columns).
285
+ *
286
+ * @param id - Matrix object to test
287
+ * @returns true if the matrix is square, false otherwise
288
+ *
289
+ * @example
290
+ * ```typescript
291
+ * // Create a 3x3 square matrix
292
+ * const m1 = matrix.new_matrix(3, 3, 0);
293
+ * const isSquare1 = matrix.is_square(m1); // Returns: true
294
+ *
295
+ * // Create a 2x3 non-square matrix
296
+ * const m2 = matrix.new_matrix(2, 3, 0);
297
+ * const isSquare2 = matrix.is_square(m2); // Returns: false
298
+ * ```
299
+ */
300
+ export function is_square(id) {
301
+ return id.rows === id.columns;
302
+ }
303
+ /**
304
+ * Test if matrix is a zero matrix
305
+ *
306
+ * The function determines if all elements of the matrix are zero.
307
+ *
308
+ * @param id - Matrix object to check (int/float)
309
+ * @returns true if all elements are zero, false otherwise
310
+ *
311
+ * @example
312
+ * ```typescript
313
+ * // Create a 2x2 zero matrix
314
+ * const m1 = matrix.new_matrix(2, 2, 0);
315
+ * const isZero1 = matrix.is_zero(m1); // Returns: true
316
+ *
317
+ * // Create a matrix with non-zero element
318
+ * const m2 = matrix.new_matrix(2, 2, 0);
319
+ * matrix.set(m2, 0, 0, 1);
320
+ * const isZero2 = matrix.is_zero(m2); // Returns: false
321
+ * ```
322
+ */
323
+ export function is_zero(id) {
324
+ for (let i = 0; i < id.rows; i++) {
325
+ for (let j = 0; j < id.columns; j++) {
326
+ if (id.data[i][j] !== 0) {
327
+ return false;
328
+ }
329
+ }
330
+ }
331
+ return true;
332
+ }
333
+ /**
334
+ * Test if matrix is binary
335
+ *
336
+ * The function determines if the matrix is binary (when all elements are 0 or 1).
337
+ *
338
+ * @param id - Matrix object to test (int/float)
339
+ * @returns true if the matrix is binary, false otherwise
340
+ *
341
+ * @example
342
+ * ```typescript
343
+ * // Create a binary matrix
344
+ * const m1 = matrix.new_matrix(2, 2, 0);
345
+ * matrix.set(m1, 0, 0, 1);
346
+ * matrix.set(m1, 1, 1, 1);
347
+ * const isBinary1 = matrix.is_binary(m1); // Returns: true
348
+ *
349
+ * // Create a non-binary matrix
350
+ * const m2 = matrix.new_matrix(2, 2, 0);
351
+ * matrix.set(m2, 0, 0, 2);
352
+ * const isBinary2 = matrix.is_binary(m2); // Returns: false
353
+ * ```
354
+ */
355
+ export function is_binary(id) {
356
+ for (let i = 0; i < id.rows; i++) {
357
+ for (let j = 0; j < id.columns; j++) {
358
+ const val = id.data[i][j];
359
+ if (val !== 0 && val !== 1) {
360
+ return false;
361
+ }
362
+ }
363
+ }
364
+ return true;
365
+ }
366
+ // ==========================================
367
+ // Row/Column Operations
368
+ // ==========================================
369
+ /**
370
+ * Add row to matrix
371
+ *
372
+ * Inserts a new row at the specified index of the matrix.
373
+ *
374
+ * @param id - A matrix object
375
+ * @param row - Optional. The index of the new row. Must be a value from 0 to matrix.rows(id).
376
+ * All existing rows with indices >= this value increase their index by one.
377
+ * Default is matrix.rows(id) (append at end).
378
+ * @param array_id - Optional. An array to use as the new row. If the matrix is empty, the array
379
+ * can be of any size. Otherwise, its size must equal matrix.columns(id).
380
+ * By default, inserts a row of undefined values.
381
+ *
382
+ * @remarks
383
+ * Indexing of rows starts at zero.
384
+ * Rather than add rows to an empty matrix, it is far more efficient to declare a matrix
385
+ * with explicit dimensions and fill it with values.
386
+ *
387
+ * @example
388
+ * ```typescript
389
+ * // Create a 2x3 matrix with zeros
390
+ * const m = matrix.new_matrix(2, 3, 0);
391
+ *
392
+ * // Add a row at the end with default values
393
+ * matrix.add_row(m);
394
+ *
395
+ * // Add an array as the first row
396
+ * const arr = [1, 2, 3];
397
+ * matrix.add_row(m, 0, arr);
398
+ * ```
399
+ */
400
+ export function add_row(id, row, array_id) {
401
+ const insertIndex = row ?? id.rows;
402
+ if (insertIndex < 0 || insertIndex > id.rows) {
403
+ throw new Error(`Row index out of bounds: ${insertIndex} for matrix with ${id.rows} rows`);
404
+ }
405
+ let newRow;
406
+ if (array_id !== undefined) {
407
+ // If matrix is not empty, array size must match columns
408
+ if (id.columns > 0 && array_id.length !== id.columns) {
409
+ throw new Error(`Array size ${array_id.length} does not match matrix columns ${id.columns}`);
410
+ }
411
+ newRow = [...array_id];
412
+ // If matrix was empty, set columns based on array
413
+ if (id.rows === 0 && id.columns === 0) {
414
+ id.columns = array_id.length;
415
+ }
416
+ }
417
+ else {
418
+ // Create row with undefined values
419
+ newRow = new Array(id.columns).fill(undefined);
420
+ }
421
+ // Insert row at specified index
422
+ id.data.splice(insertIndex, 0, newRow);
423
+ id.rows++;
424
+ }
425
+ /**
426
+ * Add column to matrix
427
+ *
428
+ * Inserts a new column at the specified index of the matrix.
429
+ *
430
+ * @param id - A matrix object
431
+ * @param column - Optional. The index of the new column. Must be a value from 0 to matrix.columns(id).
432
+ * All existing columns with indices >= this value increase their index by one.
433
+ * Default is matrix.columns(id) (append at end).
434
+ * @param array_id - Optional. An array to use as the new column. If the matrix is empty, the array
435
+ * can be of any size. Otherwise, its size must equal matrix.rows(id).
436
+ * By default, inserts a column of undefined values.
437
+ *
438
+ * @remarks
439
+ * Rather than add columns to an empty matrix, it is far more efficient to declare a matrix
440
+ * with explicit dimensions and fill it with values. Adding a column is also much slower
441
+ * than adding a row with matrix.add_row().
442
+ *
443
+ * @example
444
+ * ```typescript
445
+ * // Create a 2x3 matrix with zeros
446
+ * const m = matrix.new_matrix(2, 3, 0);
447
+ *
448
+ * // Add a column at the end with default values
449
+ * matrix.add_col(m);
450
+ *
451
+ * // Add an array as the first column
452
+ * const arr = [1, 2];
453
+ * matrix.add_col(m, 0, arr);
454
+ * ```
455
+ */
456
+ export function add_col(id, column, array_id) {
457
+ const insertIndex = column ?? id.columns;
458
+ if (insertIndex < 0 || insertIndex > id.columns) {
459
+ throw new Error(`Column index out of bounds: ${insertIndex} for matrix with ${id.columns} columns`);
460
+ }
461
+ if (array_id !== undefined) {
462
+ // If matrix is not empty, array size must match rows
463
+ if (id.rows > 0 && array_id.length !== id.rows) {
464
+ throw new Error(`Array size ${array_id.length} does not match matrix rows ${id.rows}`);
465
+ }
466
+ // If matrix was empty, set rows based on array and create empty rows
467
+ if (id.rows === 0 && id.columns === 0) {
468
+ id.rows = array_id.length;
469
+ for (let i = 0; i < array_id.length; i++) {
470
+ id.data.push([]);
471
+ }
472
+ }
473
+ // Insert value at specified column index for each row
474
+ for (let i = 0; i < id.rows; i++) {
475
+ id.data[i].splice(insertIndex, 0, array_id[i]);
476
+ }
477
+ }
478
+ else {
479
+ // Insert undefined value at specified column index for each row
480
+ for (let i = 0; i < id.rows; i++) {
481
+ id.data[i].splice(insertIndex, 0, undefined);
482
+ }
483
+ }
484
+ id.columns++;
485
+ }
486
+ /**
487
+ * Remove row from matrix
488
+ *
489
+ * Removes the row at the specified index and returns an array containing the removed row's values.
490
+ *
491
+ * @param id - A matrix object
492
+ * @param row - Optional. The index of the row to be deleted.
493
+ * Default is matrix.rows(id) - 1 (last row).
494
+ * @returns An array containing the elements of the removed row
495
+ *
496
+ * @remarks
497
+ * Indexing of rows starts at zero.
498
+ * It is far more efficient to declare matrices with explicit dimensions than to build them
499
+ * by adding or removing rows.
500
+ *
501
+ * @example
502
+ * ```typescript
503
+ * // Create a 2x2 matrix
504
+ * const m = matrix.new_matrix(2, 2, 1);
505
+ * matrix.set(m, 0, 1, 2);
506
+ * matrix.set(m, 1, 0, 3);
507
+ * matrix.set(m, 1, 1, 4);
508
+ *
509
+ * // Remove the first row
510
+ * const arr = matrix.remove_row(m, 0); // Returns: [1, 2]
511
+ * // Matrix now has 1 row
512
+ * ```
513
+ */
514
+ export function remove_row(id, row) {
515
+ const removeIndex = row ?? (id.rows - 1);
516
+ if (removeIndex < 0 || removeIndex >= id.rows) {
517
+ throw new Error(`Row index out of bounds: ${removeIndex} for matrix with ${id.rows} rows`);
518
+ }
519
+ const removedRow = id.data.splice(removeIndex, 1)[0];
520
+ id.rows--;
521
+ return removedRow;
522
+ }
523
+ /**
524
+ * Remove column from matrix
525
+ *
526
+ * Removes the column at the specified index and returns an array containing the removed column's values.
527
+ *
528
+ * @param id - A matrix object
529
+ * @param column - Optional. The index of the column to be removed.
530
+ * Default is matrix.columns(id) - 1 (last column).
531
+ * @returns An array containing the elements of the removed column
532
+ *
533
+ * @remarks
534
+ * Indexing of columns starts at zero.
535
+ * It is far more efficient to declare matrices with explicit dimensions than to build them
536
+ * by adding or removing columns. Deleting a column is also much slower than deleting a row
537
+ * with matrix.remove_row().
538
+ *
539
+ * @example
540
+ * ```typescript
541
+ * // Create a 2x2 matrix
542
+ * const m = matrix.new_matrix(2, 2, 1);
543
+ * matrix.set(m, 0, 1, 2);
544
+ * matrix.set(m, 1, 0, 3);
545
+ * matrix.set(m, 1, 1, 4);
546
+ *
547
+ * // Remove the first column
548
+ * const arr = matrix.remove_col(m, 0); // Returns: [1, 3]
549
+ * // Matrix now has 1 column
550
+ * ```
551
+ */
552
+ export function remove_col(id, column) {
553
+ const removeIndex = column ?? (id.columns - 1);
554
+ if (removeIndex < 0 || removeIndex >= id.columns) {
555
+ throw new Error(`Column index out of bounds: ${removeIndex} for matrix with ${id.columns} columns`);
556
+ }
557
+ const removedCol = [];
558
+ for (let i = 0; i < id.rows; i++) {
559
+ removedCol.push(id.data[i].splice(removeIndex, 1)[0]);
560
+ }
561
+ id.columns--;
562
+ return removedCol;
563
+ }
564
+ /**
565
+ * Swap two rows
566
+ *
567
+ * Swaps the rows at the index row1 and row2 in the matrix.
568
+ *
569
+ * @param id - A matrix object
570
+ * @param row1 - Index of the first row to be swapped
571
+ * @param row2 - Index of the second row to be swapped
572
+ *
573
+ * @remarks
574
+ * Indexing of rows starts at zero.
575
+ *
576
+ * @example
577
+ * ```typescript
578
+ * // Create a 3x2 matrix
579
+ * const m = matrix.new_matrix(3, 2, 0);
580
+ * matrix.set(m, 0, 0, 1); matrix.set(m, 0, 1, 2);
581
+ * matrix.set(m, 1, 0, 3); matrix.set(m, 1, 1, 4);
582
+ * matrix.set(m, 2, 0, 5); matrix.set(m, 2, 1, 6);
583
+ *
584
+ * // Swap first and second rows
585
+ * matrix.swap_rows(m, 0, 1);
586
+ * // Now row 0 is [3, 4] and row 1 is [1, 2]
587
+ * ```
588
+ */
589
+ export function swap_rows(id, row1, row2) {
590
+ if (row1 < 0 || row1 >= id.rows) {
591
+ throw new Error(`Row1 index out of bounds: ${row1} for matrix with ${id.rows} rows`);
592
+ }
593
+ if (row2 < 0 || row2 >= id.rows) {
594
+ throw new Error(`Row2 index out of bounds: ${row2} for matrix with ${id.rows} rows`);
595
+ }
596
+ const temp = id.data[row1];
597
+ id.data[row1] = id.data[row2];
598
+ id.data[row2] = temp;
599
+ }
600
+ /**
601
+ * Swap two columns
602
+ *
603
+ * Swaps the columns at the index column1 and column2 in the matrix.
604
+ *
605
+ * @param id - A matrix object
606
+ * @param column1 - Index of the first column to be swapped
607
+ * @param column2 - Index of the second column to be swapped
608
+ *
609
+ * @remarks
610
+ * Indexing of columns starts at zero.
611
+ *
612
+ * @example
613
+ * ```typescript
614
+ * // Create a 2x2 matrix
615
+ * const m = matrix.new_matrix(2, 2, 0);
616
+ * matrix.set(m, 0, 0, 1); matrix.set(m, 0, 1, 2);
617
+ * matrix.set(m, 1, 0, 3); matrix.set(m, 1, 1, 4);
618
+ *
619
+ * // Swap first and second columns
620
+ * matrix.swap_columns(m, 0, 1);
621
+ * // Now column 0 is [2, 4] and column 1 is [1, 3]
622
+ * ```
623
+ */
624
+ export function swap_columns(id, column1, column2) {
625
+ if (column1 < 0 || column1 >= id.columns) {
626
+ throw new Error(`Column1 index out of bounds: ${column1} for matrix with ${id.columns} columns`);
627
+ }
628
+ if (column2 < 0 || column2 >= id.columns) {
629
+ throw new Error(`Column2 index out of bounds: ${column2} for matrix with ${id.columns} columns`);
630
+ }
631
+ for (let i = 0; i < id.rows; i++) {
632
+ const temp = id.data[i][column1];
633
+ id.data[i][column1] = id.data[i][column2];
634
+ id.data[i][column2] = temp;
635
+ }
636
+ }
637
+ // ==========================================
638
+ // Matrix Transformations
639
+ // ==========================================
640
+ /**
641
+ * Matrix transpose
642
+ *
643
+ * Creates a new, transposed version of the matrix. This interchanges the row and column
644
+ * index of each element.
645
+ *
646
+ * @param id - A matrix object
647
+ * @returns A new matrix containing the transposed version
648
+ *
649
+ * @example
650
+ * ```typescript
651
+ * // Create a 2x3 matrix
652
+ * const m1 = matrix.new_matrix(2, 3, 0);
653
+ * matrix.set(m1, 0, 0, 1); matrix.set(m1, 0, 1, 2); matrix.set(m1, 0, 2, 3);
654
+ * matrix.set(m1, 1, 0, 4); matrix.set(m1, 1, 1, 5); matrix.set(m1, 1, 2, 6);
655
+ *
656
+ * // Transpose to get a 3x2 matrix
657
+ * const m2 = matrix.transpose(m1);
658
+ * // m2 = [[1, 4], [2, 5], [3, 6]]
659
+ * ```
660
+ */
661
+ export function transpose(id) {
662
+ const newData = [];
663
+ for (let j = 0; j < id.columns; j++) {
664
+ const newRow = [];
665
+ for (let i = 0; i < id.rows; i++) {
666
+ newRow.push(id.data[i][j]);
667
+ }
668
+ newData.push(newRow);
669
+ }
670
+ return {
671
+ rows: id.columns,
672
+ columns: id.rows,
673
+ data: newData
674
+ };
675
+ }
676
+ /**
677
+ * Concatenate matrices
678
+ *
679
+ * Appends the rows of m2 matrix to m1 matrix (vertical concatenation).
680
+ *
681
+ * @param id1 - Matrix object to concatenate into
682
+ * @param id2 - Matrix object whose rows will be appended to id1
683
+ * @returns Returns the id1 matrix concatenated with the id2 matrix
684
+ *
685
+ * @remarks
686
+ * The number of columns in both matrices must be identical.
687
+ *
688
+ * @example
689
+ * ```typescript
690
+ * // Create two 2x4 matrices
691
+ * const m1 = matrix.new_matrix(2, 4, 0);
692
+ * const m2 = matrix.new_matrix(2, 4, 1);
693
+ *
694
+ * // Append m2 to m1
695
+ * matrix.concat(m1, m2);
696
+ * // m1 is now 4x4
697
+ * ```
698
+ */
699
+ export function concat(id1, id2) {
700
+ if (id1.columns !== id2.columns) {
701
+ throw new Error(`Column count mismatch: ${id1.columns} vs ${id2.columns}`);
702
+ }
703
+ // Append all rows from id2 to id1
704
+ for (let i = 0; i < id2.rows; i++) {
705
+ id1.data.push([...id2.data[i]]);
706
+ }
707
+ id1.rows += id2.rows;
708
+ return id1;
709
+ }
710
+ /**
711
+ * Extract submatrix
712
+ *
713
+ * Extracts a submatrix from the matrix within the specified indices.
714
+ *
715
+ * @param id - A matrix object
716
+ * @param from_row - Row index from which extraction begins (inclusive). Default: 0
717
+ * @param to_row - Row index where extraction ends (exclusive). Default: matrix.rows(id)
718
+ * @param from_column - Column index from which extraction begins (inclusive). Default: 0
719
+ * @param to_column - Column index where extraction ends (exclusive). Default: matrix.columns(id)
720
+ * @returns A new matrix object containing the submatrix
721
+ *
722
+ * @remarks
723
+ * Indexing of rows and columns starts at zero.
724
+ *
725
+ * @example
726
+ * ```typescript
727
+ * // Create a 2x3 matrix
728
+ * const m1 = matrix.new_matrix(2, 3, 0);
729
+ * matrix.set(m1, 0, 0, 1); matrix.set(m1, 0, 1, 2); matrix.set(m1, 0, 2, 3);
730
+ * matrix.set(m1, 1, 0, 4); matrix.set(m1, 1, 1, 5); matrix.set(m1, 1, 2, 6);
731
+ *
732
+ * // Extract a 2x2 submatrix (columns 1-2)
733
+ * const m2 = matrix.submatrix(m1, 0, 2, 1, 3);
734
+ * // m2 = [[2, 3], [5, 6]]
735
+ * ```
736
+ */
737
+ export function submatrix(id, from_row = 0, to_row, from_column = 0, to_column) {
738
+ const endRow = to_row ?? id.rows;
739
+ const endCol = to_column ?? id.columns;
740
+ if (from_row < 0 || from_row > id.rows) {
741
+ throw new Error(`from_row index out of bounds: ${from_row}`);
742
+ }
743
+ if (endRow < 0 || endRow > id.rows) {
744
+ throw new Error(`to_row index out of bounds: ${endRow}`);
745
+ }
746
+ if (from_column < 0 || from_column > id.columns) {
747
+ throw new Error(`from_column index out of bounds: ${from_column}`);
748
+ }
749
+ if (endCol < 0 || endCol > id.columns) {
750
+ throw new Error(`to_column index out of bounds: ${endCol}`);
751
+ }
752
+ const newRows = endRow - from_row;
753
+ const newCols = endCol - from_column;
754
+ const newData = [];
755
+ for (let i = from_row; i < endRow; i++) {
756
+ const newRow = [];
757
+ for (let j = from_column; j < endCol; j++) {
758
+ newRow.push(id.data[i][j]);
759
+ }
760
+ newData.push(newRow);
761
+ }
762
+ return {
763
+ rows: newRows,
764
+ columns: newCols,
765
+ data: newData
766
+ };
767
+ }
768
+ /**
769
+ * Reshape matrix
770
+ *
771
+ * Rebuilds the matrix to new dimensions. The total number of elements must remain the same.
772
+ *
773
+ * @param id - A matrix object
774
+ * @param rows - The number of rows of the reshaped matrix
775
+ * @param columns - The number of columns of the reshaped matrix
776
+ *
777
+ * @remarks
778
+ * The product of rows * columns must equal the current element count.
779
+ * Elements are read row by row and placed in the new shape row by row.
780
+ *
781
+ * @example
782
+ * ```typescript
783
+ * // Create a 2x3 matrix
784
+ * const m = matrix.new_matrix(2, 3, 0);
785
+ * matrix.set(m, 0, 0, 1); matrix.set(m, 0, 1, 2); matrix.set(m, 0, 2, 3);
786
+ * matrix.set(m, 1, 0, 4); matrix.set(m, 1, 1, 5); matrix.set(m, 1, 2, 6);
787
+ *
788
+ * // Reshape to 3x2
789
+ * matrix.reshape(m, 3, 2);
790
+ * // m = [[1, 2], [3, 4], [5, 6]]
791
+ * ```
792
+ */
793
+ export function reshape(id, rows, columns) {
794
+ const totalElements = id.rows * id.columns;
795
+ const newTotalElements = rows * columns;
796
+ if (totalElements !== newTotalElements) {
797
+ throw new Error(`Cannot reshape ${id.rows}x${id.columns} (${totalElements} elements) to ${rows}x${columns} (${newTotalElements} elements)`);
798
+ }
799
+ // Flatten the matrix
800
+ const flat = [];
801
+ for (let i = 0; i < id.rows; i++) {
802
+ for (let j = 0; j < id.columns; j++) {
803
+ flat.push(id.data[i][j]);
804
+ }
805
+ }
806
+ // Rebuild with new dimensions
807
+ const newData = [];
808
+ let index = 0;
809
+ for (let i = 0; i < rows; i++) {
810
+ const newRow = [];
811
+ for (let j = 0; j < columns; j++) {
812
+ newRow.push(flat[index++]);
813
+ }
814
+ newData.push(newRow);
815
+ }
816
+ id.rows = rows;
817
+ id.columns = columns;
818
+ id.data = newData;
819
+ }
820
+ /**
821
+ * Reverse matrix
822
+ *
823
+ * Reverses the order of rows and columns in the matrix. The first row and first column
824
+ * become the last, and the last become the first.
825
+ *
826
+ * @param id - A matrix object
827
+ *
828
+ * @remarks
829
+ * This modifies the matrix in place. Both rows and columns are reversed.
830
+ *
831
+ * @example
832
+ * ```typescript
833
+ * // Create a 2x2 matrix
834
+ * const m = matrix.new_matrix(2, 2, 0);
835
+ * matrix.set(m, 0, 0, 1); matrix.set(m, 0, 1, 2);
836
+ * matrix.set(m, 1, 0, 3); matrix.set(m, 1, 1, 4);
837
+ *
838
+ * // Reverse the matrix
839
+ * matrix.reverse(m);
840
+ * // m = [[4, 3], [2, 1]]
841
+ * ```
842
+ */
843
+ export function reverse(id) {
844
+ // Reverse the order of rows
845
+ id.data.reverse();
846
+ // Reverse each row (columns)
847
+ for (let i = 0; i < id.rows; i++) {
848
+ id.data[i].reverse();
849
+ }
850
+ }
851
+ /**
852
+ * Sort matrix by column
853
+ *
854
+ * Rearranges the rows in the matrix following the sorted order of values in the specified column.
855
+ *
856
+ * @param id - A matrix object to be sorted
857
+ * @param column - Index of the column whose values determine the new order of rows. Default: 0
858
+ * @param order - The sort order: 'ascending' or 'descending'. Default: 'ascending'
859
+ *
860
+ * @remarks
861
+ * This modifies the matrix in place.
862
+ *
863
+ * @example
864
+ * ```typescript
865
+ * // Create a 2x2 matrix
866
+ * const m = matrix.new_matrix(2, 2, 0);
867
+ * matrix.set(m, 0, 0, 3); matrix.set(m, 0, 1, 4);
868
+ * matrix.set(m, 1, 0, 1); matrix.set(m, 1, 1, 2);
869
+ *
870
+ * // Sort by first column (ascending)
871
+ * matrix.sort(m);
872
+ * // m = [[1, 2], [3, 4]]
873
+ * ```
874
+ */
875
+ export function sort(id, column = 0, order = 'ascending') {
876
+ if (column < 0 || column >= id.columns) {
877
+ throw new Error(`Column index out of bounds: ${column} for matrix with ${id.columns} columns`);
878
+ }
879
+ id.data.sort((a, b) => {
880
+ const valA = a[column];
881
+ const valB = b[column];
882
+ if (typeof valA === 'number' && typeof valB === 'number') {
883
+ return order === 'ascending' ? valA - valB : valB - valA;
884
+ }
885
+ // String comparison
886
+ if (order === 'ascending') {
887
+ return valA < valB ? -1 : valA > valB ? 1 : 0;
888
+ }
889
+ else {
890
+ return valB < valA ? -1 : valB > valA ? 1 : 0;
891
+ }
892
+ });
893
+ }
894
+ // ==========================================
895
+ // Element-wise Arithmetic
896
+ // ==========================================
897
+ /**
898
+ * Matrix addition (sum)
899
+ *
900
+ * Returns a new matrix resulting from the element-wise sum of two matrices,
901
+ * or of a matrix and a scalar.
902
+ *
903
+ * @param id1 - First matrix object
904
+ * @param id2 - Second matrix object, or scalar value
905
+ * @returns A new matrix containing the sum
906
+ *
907
+ * @remarks
908
+ * When adding two matrices, they must have the same dimensions.
909
+ *
910
+ * @example
911
+ * ```typescript
912
+ * // Sum of two matrices
913
+ * const m1 = matrix.new_matrix(2, 3, 5);
914
+ * const m2 = matrix.new_matrix(2, 3, 4);
915
+ * const m3 = matrix.sum(m1, m2); // All elements are 9
916
+ *
917
+ * // Sum of matrix and scalar
918
+ * const m4 = matrix.new_matrix(2, 3, 4);
919
+ * const m5 = matrix.sum(m4, 1); // All elements are 5
920
+ * ```
921
+ */
922
+ export function sum(id1, id2) {
923
+ const newData = [];
924
+ if (typeof id2 === 'number') {
925
+ // Add scalar to each element
926
+ for (let i = 0; i < id1.rows; i++) {
927
+ const newRow = [];
928
+ for (let j = 0; j < id1.columns; j++) {
929
+ newRow.push(id1.data[i][j] + id2);
930
+ }
931
+ newData.push(newRow);
932
+ }
933
+ return {
934
+ rows: id1.rows,
935
+ columns: id1.columns,
936
+ data: newData
937
+ };
938
+ }
939
+ else {
940
+ // Add two matrices element-wise
941
+ if (id1.rows !== id2.rows || id1.columns !== id2.columns) {
942
+ throw new Error(`Matrix dimensions must match: ${id1.rows}x${id1.columns} vs ${id2.rows}x${id2.columns}`);
943
+ }
944
+ for (let i = 0; i < id1.rows; i++) {
945
+ const newRow = [];
946
+ for (let j = 0; j < id1.columns; j++) {
947
+ newRow.push(id1.data[i][j] + id2.data[i][j]);
948
+ }
949
+ newData.push(newRow);
950
+ }
951
+ return {
952
+ rows: id1.rows,
953
+ columns: id1.columns,
954
+ data: newData
955
+ };
956
+ }
957
+ }
958
+ /**
959
+ * Matrix subtraction (diff)
960
+ *
961
+ * Returns a new matrix resulting from the element-wise subtraction between two matrices,
962
+ * or of a matrix and a scalar.
963
+ *
964
+ * @param id1 - Matrix to subtract from
965
+ * @param id2 - Matrix object or scalar value to be subtracted
966
+ * @returns A new matrix containing the difference
967
+ *
968
+ * @remarks
969
+ * When subtracting two matrices, they must have the same dimensions.
970
+ *
971
+ * @example
972
+ * ```typescript
973
+ * // Difference between two matrices
974
+ * const m1 = matrix.new_matrix(2, 3, 5);
975
+ * const m2 = matrix.new_matrix(2, 3, 4);
976
+ * const m3 = matrix.diff(m1, m2); // All elements are 1
977
+ *
978
+ * // Difference between matrix and scalar
979
+ * const m4 = matrix.new_matrix(2, 3, 4);
980
+ * const m5 = matrix.diff(m4, 1); // All elements are 3
981
+ * ```
982
+ */
983
+ export function diff(id1, id2) {
984
+ const newData = [];
985
+ if (typeof id2 === 'number') {
986
+ // Subtract scalar from each element
987
+ for (let i = 0; i < id1.rows; i++) {
988
+ const newRow = [];
989
+ for (let j = 0; j < id1.columns; j++) {
990
+ newRow.push(id1.data[i][j] - id2);
991
+ }
992
+ newData.push(newRow);
993
+ }
994
+ return {
995
+ rows: id1.rows,
996
+ columns: id1.columns,
997
+ data: newData
998
+ };
999
+ }
1000
+ else {
1001
+ // Subtract two matrices element-wise
1002
+ if (id1.rows !== id2.rows || id1.columns !== id2.columns) {
1003
+ throw new Error(`Matrix dimensions must match: ${id1.rows}x${id1.columns} vs ${id2.rows}x${id2.columns}`);
1004
+ }
1005
+ for (let i = 0; i < id1.rows; i++) {
1006
+ const newRow = [];
1007
+ for (let j = 0; j < id1.columns; j++) {
1008
+ newRow.push(id1.data[i][j] - id2.data[i][j]);
1009
+ }
1010
+ newData.push(newRow);
1011
+ }
1012
+ return {
1013
+ rows: id1.rows,
1014
+ columns: id1.columns,
1015
+ data: newData
1016
+ };
1017
+ }
1018
+ }
1019
+ // ==========================================
1020
+ // Statistical Functions
1021
+ // ==========================================
1022
+ /**
1023
+ * Average of all elements
1024
+ *
1025
+ * Calculates the average of all elements in the matrix.
1026
+ *
1027
+ * @param id - A matrix object
1028
+ * @returns The average value from the matrix
1029
+ *
1030
+ * @example
1031
+ * ```typescript
1032
+ * // Create a 2x2 matrix
1033
+ * const m = matrix.new_matrix(2, 2, 0);
1034
+ * matrix.set(m, 0, 0, 1); matrix.set(m, 0, 1, 2);
1035
+ * matrix.set(m, 1, 0, 3); matrix.set(m, 1, 1, 4);
1036
+ *
1037
+ * const avg = matrix.avg(m); // Returns: 2.5
1038
+ * ```
1039
+ */
1040
+ export function avg(id) {
1041
+ if (id.rows === 0 || id.columns === 0) {
1042
+ return NaN;
1043
+ }
1044
+ let total = 0;
1045
+ let count = 0;
1046
+ for (let i = 0; i < id.rows; i++) {
1047
+ for (let j = 0; j < id.columns; j++) {
1048
+ const val = id.data[i][j];
1049
+ if (val !== null && val !== undefined && !isNaN(val)) {
1050
+ total += val;
1051
+ count++;
1052
+ }
1053
+ }
1054
+ }
1055
+ return count === 0 ? NaN : total / count;
1056
+ }
1057
+ /**
1058
+ * Minimum element
1059
+ *
1060
+ * Returns the smallest value from the matrix elements.
1061
+ *
1062
+ * @param id - A matrix object
1063
+ * @returns The smallest value from the matrix
1064
+ *
1065
+ * @example
1066
+ * ```typescript
1067
+ * // Create a 2x2 matrix
1068
+ * const m = matrix.new_matrix(2, 2, 0);
1069
+ * matrix.set(m, 0, 0, 1); matrix.set(m, 0, 1, 2);
1070
+ * matrix.set(m, 1, 0, 3); matrix.set(m, 1, 1, 4);
1071
+ *
1072
+ * const minVal = matrix.min(m); // Returns: 1
1073
+ * ```
1074
+ */
1075
+ export function min(id) {
1076
+ if (id.rows === 0 || id.columns === 0) {
1077
+ return NaN;
1078
+ }
1079
+ let minVal = Infinity;
1080
+ for (let i = 0; i < id.rows; i++) {
1081
+ for (let j = 0; j < id.columns; j++) {
1082
+ const val = id.data[i][j];
1083
+ if (val !== null && val !== undefined && !isNaN(val) && val < minVal) {
1084
+ minVal = val;
1085
+ }
1086
+ }
1087
+ }
1088
+ return minVal === Infinity ? NaN : minVal;
1089
+ }
1090
+ /**
1091
+ * Maximum element
1092
+ *
1093
+ * Returns the largest value from the matrix elements.
1094
+ *
1095
+ * @param id - A matrix object
1096
+ * @returns The largest value from the matrix
1097
+ *
1098
+ * @example
1099
+ * ```typescript
1100
+ * // Create a 2x2 matrix
1101
+ * const m = matrix.new_matrix(2, 2, 0);
1102
+ * matrix.set(m, 0, 0, 1); matrix.set(m, 0, 1, 2);
1103
+ * matrix.set(m, 1, 0, 3); matrix.set(m, 1, 1, 4);
1104
+ *
1105
+ * const maxVal = matrix.max(m); // Returns: 4
1106
+ * ```
1107
+ */
1108
+ export function max(id) {
1109
+ if (id.rows === 0 || id.columns === 0) {
1110
+ return NaN;
1111
+ }
1112
+ let maxVal = -Infinity;
1113
+ for (let i = 0; i < id.rows; i++) {
1114
+ for (let j = 0; j < id.columns; j++) {
1115
+ const val = id.data[i][j];
1116
+ if (val !== null && val !== undefined && !isNaN(val) && val > maxVal) {
1117
+ maxVal = val;
1118
+ }
1119
+ }
1120
+ }
1121
+ return maxVal === -Infinity ? NaN : maxVal;
1122
+ }
1123
+ /**
1124
+ * Median element
1125
+ *
1126
+ * Calculates the median ("the middle" value) of matrix elements.
1127
+ *
1128
+ * @param id - A matrix object
1129
+ * @returns The median value from the matrix
1130
+ *
1131
+ * @remarks
1132
+ * NA elements of the matrix are not considered when calculating the median.
1133
+ *
1134
+ * @example
1135
+ * ```typescript
1136
+ * // Create a 2x2 matrix
1137
+ * const m = matrix.new_matrix(2, 2, 0);
1138
+ * matrix.set(m, 0, 0, 1); matrix.set(m, 0, 1, 2);
1139
+ * matrix.set(m, 1, 0, 3); matrix.set(m, 1, 1, 4);
1140
+ *
1141
+ * const medianVal = matrix.median(m); // Returns: 2.5
1142
+ * ```
1143
+ */
1144
+ export function median(id) {
1145
+ if (id.rows === 0 || id.columns === 0) {
1146
+ return NaN;
1147
+ }
1148
+ // Flatten and filter out NaN/null/undefined
1149
+ const values = [];
1150
+ for (let i = 0; i < id.rows; i++) {
1151
+ for (let j = 0; j < id.columns; j++) {
1152
+ const val = id.data[i][j];
1153
+ if (val !== null && val !== undefined && !isNaN(val)) {
1154
+ values.push(val);
1155
+ }
1156
+ }
1157
+ }
1158
+ if (values.length === 0) {
1159
+ return NaN;
1160
+ }
1161
+ values.sort((a, b) => a - b);
1162
+ const mid = Math.floor(values.length / 2);
1163
+ if (values.length % 2 === 0) {
1164
+ return (values[mid - 1] + values[mid]) / 2;
1165
+ }
1166
+ else {
1167
+ return values[mid];
1168
+ }
1169
+ }
1170
+ /**
1171
+ * Mode (most frequent element)
1172
+ *
1173
+ * Calculates the mode of the matrix, which is the most frequently occurring value.
1174
+ * When there are multiple values occurring equally frequently, returns the smallest.
1175
+ *
1176
+ * @param id - A matrix object
1177
+ * @returns The most frequently occurring value, or the smallest if tie
1178
+ *
1179
+ * @remarks
1180
+ * NA elements of the matrix are not considered when calculating the mode.
1181
+ *
1182
+ * @example
1183
+ * ```typescript
1184
+ * // Create a 2x2 matrix
1185
+ * const m = matrix.new_matrix(2, 2, 0);
1186
+ * matrix.set(m, 0, 0, 0); matrix.set(m, 0, 1, 0);
1187
+ * matrix.set(m, 1, 0, 1); matrix.set(m, 1, 1, 1);
1188
+ *
1189
+ * const modeVal = matrix.mode(m); // Returns: 0 (tie, so smallest)
1190
+ * ```
1191
+ */
1192
+ export function mode(id) {
1193
+ if (id.rows === 0 || id.columns === 0) {
1194
+ return NaN;
1195
+ }
1196
+ const frequency = new Map();
1197
+ let maxFreq = 0;
1198
+ let modeValue = NaN;
1199
+ for (let i = 0; i < id.rows; i++) {
1200
+ for (let j = 0; j < id.columns; j++) {
1201
+ const val = id.data[i][j];
1202
+ if (val !== null && val !== undefined && !isNaN(val)) {
1203
+ const freq = (frequency.get(val) || 0) + 1;
1204
+ frequency.set(val, freq);
1205
+ // Update mode if higher frequency, or same frequency but smaller value
1206
+ if (freq > maxFreq || (freq === maxFreq && val < modeValue)) {
1207
+ maxFreq = freq;
1208
+ modeValue = val;
1209
+ }
1210
+ }
1211
+ }
1212
+ }
1213
+ return modeValue;
1214
+ }
1215
+ /**
1216
+ * Matrix trace
1217
+ *
1218
+ * Calculates the trace of a matrix (the sum of the main diagonal's elements).
1219
+ *
1220
+ * @param id - A matrix object (must be square)
1221
+ * @returns The trace of the matrix
1222
+ *
1223
+ * @remarks
1224
+ * The matrix must be square. Throws an error for non-square matrices.
1225
+ *
1226
+ * @example
1227
+ * ```typescript
1228
+ * // Create a 2x2 matrix
1229
+ * const m = matrix.new_matrix(2, 2, 0);
1230
+ * matrix.set(m, 0, 0, 1); matrix.set(m, 0, 1, 2);
1231
+ * matrix.set(m, 1, 0, 3); matrix.set(m, 1, 1, 4);
1232
+ *
1233
+ * const tr = matrix.trace(m); // Returns: 5 (1 + 4)
1234
+ * ```
1235
+ */
1236
+ export function trace(id) {
1237
+ if (!is_square(id)) {
1238
+ throw new Error(`Matrix must be square for trace calculation: ${id.rows}x${id.columns}`);
1239
+ }
1240
+ if (id.rows === 0) {
1241
+ return 0;
1242
+ }
1243
+ let sum = 0;
1244
+ for (let i = 0; i < id.rows; i++) {
1245
+ const val = id.data[i][i];
1246
+ if (val !== null && val !== undefined && !isNaN(val)) {
1247
+ sum += val;
1248
+ }
1249
+ }
1250
+ return sum;
1251
+ }
1252
+ // ==========================================
1253
+ // Boolean Checks
1254
+ // ==========================================
1255
+ /**
1256
+ * Test if diagonal matrix
1257
+ *
1258
+ * Determines if the matrix is diagonal (all elements outside the main diagonal are zero).
1259
+ *
1260
+ * @param id - Matrix object to test
1261
+ * @returns true if the matrix is diagonal, false otherwise
1262
+ *
1263
+ * @remarks
1264
+ * Returns false with non-square matrices.
1265
+ *
1266
+ * @example
1267
+ * ```typescript
1268
+ * // Create a diagonal matrix
1269
+ * const m = matrix.new_matrix(3, 3, 0);
1270
+ * matrix.set(m, 0, 0, 1);
1271
+ * matrix.set(m, 1, 1, 2);
1272
+ * matrix.set(m, 2, 2, 3);
1273
+ *
1274
+ * const isDiag = matrix.is_diagonal(m); // Returns: true
1275
+ * ```
1276
+ */
1277
+ export function is_diagonal(id) {
1278
+ if (!is_square(id)) {
1279
+ return false;
1280
+ }
1281
+ for (let i = 0; i < id.rows; i++) {
1282
+ for (let j = 0; j < id.columns; j++) {
1283
+ if (i !== j && id.data[i][j] !== 0) {
1284
+ return false;
1285
+ }
1286
+ }
1287
+ }
1288
+ return true;
1289
+ }
1290
+ /**
1291
+ * Test if identity matrix
1292
+ *
1293
+ * Determines if a matrix is an identity matrix (elements with ones on the main diagonal
1294
+ * and zeros elsewhere).
1295
+ *
1296
+ * @param id - Matrix object to test
1297
+ * @returns true if id is an identity matrix, false otherwise
1298
+ *
1299
+ * @remarks
1300
+ * Returns false with non-square matrices.
1301
+ *
1302
+ * @example
1303
+ * ```typescript
1304
+ * // Create an identity matrix
1305
+ * const m = matrix.new_matrix(3, 3, 0);
1306
+ * matrix.set(m, 0, 0, 1);
1307
+ * matrix.set(m, 1, 1, 1);
1308
+ * matrix.set(m, 2, 2, 1);
1309
+ *
1310
+ * const isIdent = matrix.is_identity(m); // Returns: true
1311
+ * ```
1312
+ */
1313
+ export function is_identity(id) {
1314
+ if (!is_square(id)) {
1315
+ return false;
1316
+ }
1317
+ for (let i = 0; i < id.rows; i++) {
1318
+ for (let j = 0; j < id.columns; j++) {
1319
+ const val = id.data[i][j];
1320
+ if (i === j) {
1321
+ if (val !== 1) {
1322
+ return false;
1323
+ }
1324
+ }
1325
+ else {
1326
+ if (val !== 0) {
1327
+ return false;
1328
+ }
1329
+ }
1330
+ }
1331
+ }
1332
+ return true;
1333
+ }
1334
+ /**
1335
+ * Test if symmetric matrix
1336
+ *
1337
+ * Determines if a square matrix is symmetric (elements are symmetric with respect
1338
+ * to the main diagonal, i.e., matrix equals its transpose).
1339
+ *
1340
+ * @param id - Matrix object to test
1341
+ * @returns true if the matrix is symmetric, false otherwise
1342
+ *
1343
+ * @remarks
1344
+ * Returns false with non-square matrices.
1345
+ *
1346
+ * @example
1347
+ * ```typescript
1348
+ * // Create a symmetric matrix
1349
+ * const m = matrix.new_matrix(3, 3, 0);
1350
+ * matrix.set(m, 0, 0, 1); matrix.set(m, 0, 1, 2); matrix.set(m, 0, 2, 3);
1351
+ * matrix.set(m, 1, 0, 2); matrix.set(m, 1, 1, 4); matrix.set(m, 1, 2, 5);
1352
+ * matrix.set(m, 2, 0, 3); matrix.set(m, 2, 1, 5); matrix.set(m, 2, 2, 6);
1353
+ *
1354
+ * const isSym = matrix.is_symmetric(m); // Returns: true
1355
+ * ```
1356
+ */
1357
+ export function is_symmetric(id) {
1358
+ if (!is_square(id)) {
1359
+ return false;
1360
+ }
1361
+ for (let i = 0; i < id.rows; i++) {
1362
+ for (let j = i + 1; j < id.columns; j++) {
1363
+ if (id.data[i][j] !== id.data[j][i]) {
1364
+ return false;
1365
+ }
1366
+ }
1367
+ }
1368
+ return true;
1369
+ }
1370
+ /**
1371
+ * Test if antisymmetric (skew-symmetric) matrix
1372
+ *
1373
+ * Determines if a matrix is antisymmetric (its transpose equals its negative).
1374
+ * A[i][j] = -A[j][i] for all i, j, and diagonal elements must be 0.
1375
+ *
1376
+ * @param id - Matrix object to test
1377
+ * @returns true if the matrix is antisymmetric, false otherwise
1378
+ *
1379
+ * @remarks
1380
+ * Returns false with non-square matrices.
1381
+ *
1382
+ * @example
1383
+ * ```typescript
1384
+ * // Create an antisymmetric matrix
1385
+ * const m = matrix.new_matrix(3, 3, 0);
1386
+ * matrix.set(m, 0, 1, 2); matrix.set(m, 0, 2, -1);
1387
+ * matrix.set(m, 1, 0, -2); matrix.set(m, 1, 2, 3);
1388
+ * matrix.set(m, 2, 0, 1); matrix.set(m, 2, 1, -3);
1389
+ *
1390
+ * const isAntiSym = matrix.is_antisymmetric(m); // Returns: true
1391
+ * ```
1392
+ */
1393
+ export function is_antisymmetric(id) {
1394
+ if (!is_square(id)) {
1395
+ return false;
1396
+ }
1397
+ for (let i = 0; i < id.rows; i++) {
1398
+ // Diagonal elements must be 0
1399
+ if (id.data[i][i] !== 0) {
1400
+ return false;
1401
+ }
1402
+ for (let j = i + 1; j < id.columns; j++) {
1403
+ const upperVal = id.data[i][j];
1404
+ const lowerVal = id.data[j][i];
1405
+ if (upperVal !== -lowerVal) {
1406
+ return false;
1407
+ }
1408
+ }
1409
+ }
1410
+ return true;
1411
+ }
1412
+ /**
1413
+ * Test if triangular matrix
1414
+ *
1415
+ * Determines if the matrix is triangular (if all elements above or below the main
1416
+ * diagonal are zero).
1417
+ *
1418
+ * @param id - Matrix object to test
1419
+ * @returns true if the matrix is triangular (upper or lower), false otherwise
1420
+ *
1421
+ * @remarks
1422
+ * Returns false with non-square matrices.
1423
+ * Returns true if the matrix is either upper triangular or lower triangular.
1424
+ *
1425
+ * @example
1426
+ * ```typescript
1427
+ * // Create an upper triangular matrix
1428
+ * const m = matrix.new_matrix(3, 3, 0);
1429
+ * matrix.set(m, 0, 0, 1); matrix.set(m, 0, 1, 2); matrix.set(m, 0, 2, 3);
1430
+ * matrix.set(m, 1, 1, 4); matrix.set(m, 1, 2, 5);
1431
+ * matrix.set(m, 2, 2, 6);
1432
+ *
1433
+ * const isTri = matrix.is_triangular(m); // Returns: true
1434
+ * ```
1435
+ */
1436
+ export function is_triangular(id) {
1437
+ if (!is_square(id)) {
1438
+ return false;
1439
+ }
1440
+ // Check if upper triangular (all elements below diagonal are 0)
1441
+ let isUpper = true;
1442
+ for (let i = 1; i < id.rows && isUpper; i++) {
1443
+ for (let j = 0; j < i && isUpper; j++) {
1444
+ if (id.data[i][j] !== 0) {
1445
+ isUpper = false;
1446
+ }
1447
+ }
1448
+ }
1449
+ if (isUpper) {
1450
+ return true;
1451
+ }
1452
+ // Check if lower triangular (all elements above diagonal are 0)
1453
+ let isLower = true;
1454
+ for (let i = 0; i < id.rows - 1 && isLower; i++) {
1455
+ for (let j = i + 1; j < id.columns && isLower; j++) {
1456
+ if (id.data[i][j] !== 0) {
1457
+ isLower = false;
1458
+ }
1459
+ }
1460
+ }
1461
+ return isLower;
1462
+ }
1463
+ /**
1464
+ * Test if antidiagonal matrix
1465
+ *
1466
+ * Determines if the matrix is anti-diagonal (all elements outside the secondary
1467
+ * diagonal are zero).
1468
+ *
1469
+ * @param id - Matrix object to test
1470
+ * @returns true if the matrix is anti-diagonal, false otherwise
1471
+ *
1472
+ * @remarks
1473
+ * Returns false with non-square matrices.
1474
+ * The anti-diagonal runs from top-right to bottom-left.
1475
+ *
1476
+ * @example
1477
+ * ```typescript
1478
+ * // Create an antidiagonal matrix
1479
+ * const m = matrix.new_matrix(3, 3, 0);
1480
+ * matrix.set(m, 0, 2, 1);
1481
+ * matrix.set(m, 1, 1, 2);
1482
+ * matrix.set(m, 2, 0, 3);
1483
+ *
1484
+ * const isAntiDiag = matrix.is_antidiagonal(m); // Returns: true
1485
+ * ```
1486
+ */
1487
+ export function is_antidiagonal(id) {
1488
+ if (!is_square(id)) {
1489
+ return false;
1490
+ }
1491
+ const n = id.rows;
1492
+ for (let i = 0; i < n; i++) {
1493
+ for (let j = 0; j < n; j++) {
1494
+ // Anti-diagonal position: i + j === n - 1
1495
+ const isAntiDiag = (i + j === n - 1);
1496
+ if (!isAntiDiag && id.data[i][j] !== 0) {
1497
+ return false;
1498
+ }
1499
+ }
1500
+ }
1501
+ return true;
1502
+ }
1503
+ /**
1504
+ * Test if stochastic matrix
1505
+ *
1506
+ * Determines if the matrix is stochastic (all elements are non-negative and all
1507
+ * row sums equal 1).
1508
+ *
1509
+ * @param id - Matrix object to test
1510
+ * @returns true if the matrix is stochastic, false otherwise
1511
+ *
1512
+ * @remarks
1513
+ * A right stochastic matrix has rows that sum to 1.
1514
+ *
1515
+ * @example
1516
+ * ```typescript
1517
+ * // Create a stochastic matrix
1518
+ * const m = matrix.new_matrix(2, 2, 0);
1519
+ * matrix.set(m, 0, 0, 0.5); matrix.set(m, 0, 1, 0.5);
1520
+ * matrix.set(m, 1, 0, 0.3); matrix.set(m, 1, 1, 0.7);
1521
+ *
1522
+ * const isStoch = matrix.is_stochastic(m); // Returns: true
1523
+ * ```
1524
+ */
1525
+ export function is_stochastic(id) {
1526
+ if (id.rows === 0 || id.columns === 0) {
1527
+ return false;
1528
+ }
1529
+ const tolerance = 1e-10;
1530
+ for (let i = 0; i < id.rows; i++) {
1531
+ let rowSum = 0;
1532
+ for (let j = 0; j < id.columns; j++) {
1533
+ const val = id.data[i][j];
1534
+ // All elements must be non-negative
1535
+ if (val < 0) {
1536
+ return false;
1537
+ }
1538
+ rowSum += val;
1539
+ }
1540
+ // Row sum must equal 1 (with tolerance for floating point errors)
1541
+ if (Math.abs(rowSum - 1) > tolerance) {
1542
+ return false;
1543
+ }
1544
+ }
1545
+ return true;
1546
+ }
1547
+ // ==========================================
1548
+ // Linear Algebra Functions (Phase 3)
1549
+ // ==========================================
1550
+ /**
1551
+ * Epsilon for floating-point comparisons
1552
+ */
1553
+ const EPSILON = 1e-10;
1554
+ /**
1555
+ * Helper: Create identity matrix of given size
1556
+ */
1557
+ function createIdentity(n) {
1558
+ const m = new_matrix(n, n, 0);
1559
+ for (let i = 0; i < n; i++) {
1560
+ m.data[i][i] = 1;
1561
+ }
1562
+ return m;
1563
+ }
1564
+ /**
1565
+ * Matrix multiplication
1566
+ *
1567
+ * Returns a new matrix resulting from the product between two matrices,
1568
+ * or between a matrix and a scalar, or between a matrix and a vector (array).
1569
+ *
1570
+ * @param id1 - First matrix object
1571
+ * @param id2 - Second matrix object, scalar value, or array (vector)
1572
+ * @returns A new matrix containing the product, or array for matrix × vector
1573
+ *
1574
+ * @remarks
1575
+ * For matrix × matrix: id1's columns must equal id2's rows.
1576
+ * For matrix × vector: the array length must equal id1's columns.
1577
+ * Time complexity: O(n³) for n×n matrices.
1578
+ *
1579
+ * @example
1580
+ * ```typescript
1581
+ * // Product of two matrices
1582
+ * const m1 = matrix.new_matrix(6, 2, 5);
1583
+ * const m2 = matrix.new_matrix(2, 3, 4);
1584
+ * const m3 = matrix.mult(m1, m2); // 6x3 matrix with values 40
1585
+ *
1586
+ * // Product of matrix and scalar
1587
+ * const m4 = matrix.new_matrix(2, 3, 4);
1588
+ * const m5 = matrix.mult(m4, 5); // All elements are 20
1589
+ *
1590
+ * // Product of matrix and vector
1591
+ * const m6 = matrix.new_matrix(2, 3, 4);
1592
+ * const arr = [1, 1, 1];
1593
+ * const result = matrix.mult(m6, arr); // [12, 12]
1594
+ * ```
1595
+ */
1596
+ export function mult(id1, id2) {
1597
+ // Matrix × Scalar
1598
+ if (typeof id2 === 'number') {
1599
+ const newData = [];
1600
+ for (let i = 0; i < id1.rows; i++) {
1601
+ const newRow = [];
1602
+ for (let j = 0; j < id1.columns; j++) {
1603
+ newRow.push(id1.data[i][j] * id2);
1604
+ }
1605
+ newData.push(newRow);
1606
+ }
1607
+ return {
1608
+ rows: id1.rows,
1609
+ columns: id1.columns,
1610
+ data: newData
1611
+ };
1612
+ }
1613
+ // Matrix × Vector (array)
1614
+ if (Array.isArray(id2) && !('rows' in id2)) {
1615
+ const vec = id2;
1616
+ if (vec.length !== id1.columns) {
1617
+ throw new Error(`Vector length ${vec.length} must equal matrix columns ${id1.columns}`);
1618
+ }
1619
+ const result = [];
1620
+ for (let i = 0; i < id1.rows; i++) {
1621
+ let sum = 0;
1622
+ for (let j = 0; j < id1.columns; j++) {
1623
+ sum += id1.data[i][j] * vec[j];
1624
+ }
1625
+ result.push(sum);
1626
+ }
1627
+ return result;
1628
+ }
1629
+ // Matrix × Matrix
1630
+ const m2 = id2;
1631
+ if (id1.columns !== m2.rows) {
1632
+ throw new Error(`Matrix multiplication dimension mismatch: ${id1.rows}x${id1.columns} × ${m2.rows}x${m2.columns}. First matrix columns (${id1.columns}) must equal second matrix rows (${m2.rows})`);
1633
+ }
1634
+ const newRows = id1.rows;
1635
+ const newCols = m2.columns;
1636
+ const newData = [];
1637
+ for (let i = 0; i < newRows; i++) {
1638
+ const newRow = [];
1639
+ for (let j = 0; j < newCols; j++) {
1640
+ let sum = 0;
1641
+ for (let k = 0; k < id1.columns; k++) {
1642
+ sum += id1.data[i][k] * m2.data[k][j];
1643
+ }
1644
+ newRow.push(sum);
1645
+ }
1646
+ newData.push(newRow);
1647
+ }
1648
+ return {
1649
+ rows: newRows,
1650
+ columns: newCols,
1651
+ data: newData
1652
+ };
1653
+ }
1654
+ /**
1655
+ * Matrix power
1656
+ *
1657
+ * Calculates the product of the matrix by itself 'power' times.
1658
+ * Uses repeated squaring for efficiency: O(n³ log p) for n×n matrix and power p.
1659
+ *
1660
+ * @param id - A matrix object (must be square)
1661
+ * @param power - The number of times the matrix will be multiplied by itself
1662
+ * @returns A new matrix that is id raised to the specified power
1663
+ *
1664
+ * @remarks
1665
+ * The matrix must be square.
1666
+ * power=0 returns the identity matrix.
1667
+ * Negative powers compute the inverse first, then raise to the positive power.
1668
+ *
1669
+ * @example
1670
+ * ```typescript
1671
+ * // Create a 2x2 matrix
1672
+ * const m1 = matrix.new_matrix(2, 2, 2);
1673
+ * // Calculate the power of three
1674
+ * const m2 = matrix.pow(m1, 3);
1675
+ * // m2 = m1 × m1 × m1
1676
+ * ```
1677
+ */
1678
+ export function pow(id, power) {
1679
+ if (!is_square(id)) {
1680
+ throw new Error(`Matrix must be square for power calculation: ${id.rows}x${id.columns}`);
1681
+ }
1682
+ const n = id.rows;
1683
+ // Handle power = 0: return identity matrix
1684
+ if (power === 0) {
1685
+ return createIdentity(n);
1686
+ }
1687
+ // Handle negative powers: compute inverse then raise to positive power
1688
+ let base;
1689
+ let p = power;
1690
+ if (power < 0) {
1691
+ const inverse = inv(id);
1692
+ if (inverse === null) {
1693
+ throw new Error('Cannot compute negative power of singular matrix');
1694
+ }
1695
+ base = inverse;
1696
+ p = -power;
1697
+ }
1698
+ else {
1699
+ base = copy(id);
1700
+ }
1701
+ // Repeated squaring algorithm
1702
+ let result = createIdentity(n);
1703
+ while (p > 0) {
1704
+ if (p % 2 === 1) {
1705
+ result = mult(result, base);
1706
+ }
1707
+ base = mult(base, base);
1708
+ p = Math.floor(p / 2);
1709
+ }
1710
+ return result;
1711
+ }
1712
+ /**
1713
+ * Matrix determinant
1714
+ *
1715
+ * Computes the determinant of a square matrix using LU decomposition
1716
+ * with partial pivoting.
1717
+ *
1718
+ * @param id - A matrix object (must be square)
1719
+ * @returns The determinant value
1720
+ *
1721
+ * @remarks
1722
+ * Function calculation based on the LU decomposition algorithm.
1723
+ * Time complexity: O(n³)
1724
+ *
1725
+ * @example
1726
+ * ```typescript
1727
+ * // Create a 2x2 matrix
1728
+ * const m = matrix.new_matrix(2, 2, NaN);
1729
+ * matrix.set(m, 0, 0, 3);
1730
+ * matrix.set(m, 0, 1, 7);
1731
+ * matrix.set(m, 1, 0, 1);
1732
+ * matrix.set(m, 1, 1, -4);
1733
+ *
1734
+ * const d = matrix.det(m); // Returns: -19
1735
+ * ```
1736
+ */
1737
+ export function det(id) {
1738
+ if (!is_square(id)) {
1739
+ throw new Error(`Matrix must be square for determinant calculation: ${id.rows}x${id.columns}`);
1740
+ }
1741
+ const n = id.rows;
1742
+ if (n === 0) {
1743
+ return 1; // Empty matrix has determinant 1 by convention
1744
+ }
1745
+ if (n === 1) {
1746
+ return id.data[0][0];
1747
+ }
1748
+ if (n === 2) {
1749
+ return id.data[0][0] * id.data[1][1] - id.data[0][1] * id.data[1][0];
1750
+ }
1751
+ // LU decomposition with partial pivoting
1752
+ // Make a copy to work with
1753
+ const a = id.data.map(row => [...row]);
1754
+ let determinant = 1;
1755
+ let swapCount = 0;
1756
+ for (let col = 0; col < n; col++) {
1757
+ // Find pivot (partial pivoting)
1758
+ let maxRow = col;
1759
+ let maxVal = Math.abs(a[col][col]);
1760
+ for (let row = col + 1; row < n; row++) {
1761
+ const absVal = Math.abs(a[row][col]);
1762
+ if (absVal > maxVal) {
1763
+ maxVal = absVal;
1764
+ maxRow = row;
1765
+ }
1766
+ }
1767
+ // Swap rows if needed
1768
+ if (maxRow !== col) {
1769
+ const temp = a[col];
1770
+ a[col] = a[maxRow];
1771
+ a[maxRow] = temp;
1772
+ swapCount++;
1773
+ }
1774
+ // If pivot is zero, determinant is zero
1775
+ const pivot = a[col][col];
1776
+ if (Math.abs(pivot) < EPSILON) {
1777
+ return 0;
1778
+ }
1779
+ determinant *= pivot;
1780
+ // Eliminate below pivot
1781
+ for (let row = col + 1; row < n; row++) {
1782
+ const factor = a[row][col] / pivot;
1783
+ for (let j = col; j < n; j++) {
1784
+ a[row][j] = a[row][j] - factor * a[col][j];
1785
+ }
1786
+ }
1787
+ }
1788
+ // Adjust sign based on row swaps
1789
+ if (swapCount % 2 === 1) {
1790
+ determinant = -determinant;
1791
+ }
1792
+ return determinant;
1793
+ }
1794
+ /**
1795
+ * Matrix inverse
1796
+ *
1797
+ * Computes the inverse of a square matrix using Gauss-Jordan elimination
1798
+ * with partial pivoting.
1799
+ *
1800
+ * @param id - A matrix object (must be square and non-singular)
1801
+ * @returns A new matrix that is the inverse, or null if singular
1802
+ *
1803
+ * @remarks
1804
+ * Function calculation based on the LU decomposition algorithm.
1805
+ * Returns null for singular matrices (det = 0).
1806
+ * Time complexity: O(n³)
1807
+ *
1808
+ * @example
1809
+ * ```typescript
1810
+ * // Create a 2x2 matrix
1811
+ * const m1 = matrix.new_matrix(2, 2, NaN);
1812
+ * matrix.set(m1, 0, 0, 1);
1813
+ * matrix.set(m1, 0, 1, 2);
1814
+ * matrix.set(m1, 1, 0, 3);
1815
+ * matrix.set(m1, 1, 1, 4);
1816
+ *
1817
+ * const m2 = matrix.inv(m1);
1818
+ * // m2 = [[-2, 1], [1.5, -0.5]]
1819
+ * ```
1820
+ */
1821
+ export function inv(id) {
1822
+ if (!is_square(id)) {
1823
+ throw new Error(`Matrix must be square for inverse calculation: ${id.rows}x${id.columns}`);
1824
+ }
1825
+ const n = id.rows;
1826
+ if (n === 0) {
1827
+ return new_matrix(0, 0, 0);
1828
+ }
1829
+ // Create augmented matrix [A | I]
1830
+ const aug = [];
1831
+ for (let i = 0; i < n; i++) {
1832
+ const row = [];
1833
+ for (let j = 0; j < n; j++) {
1834
+ row.push(id.data[i][j]);
1835
+ }
1836
+ for (let j = 0; j < n; j++) {
1837
+ row.push(i === j ? 1 : 0);
1838
+ }
1839
+ aug.push(row);
1840
+ }
1841
+ // Gauss-Jordan elimination with partial pivoting
1842
+ for (let col = 0; col < n; col++) {
1843
+ // Find pivot
1844
+ let maxRow = col;
1845
+ let maxVal = Math.abs(aug[col][col]);
1846
+ for (let row = col + 1; row < n; row++) {
1847
+ const absVal = Math.abs(aug[row][col]);
1848
+ if (absVal > maxVal) {
1849
+ maxVal = absVal;
1850
+ maxRow = row;
1851
+ }
1852
+ }
1853
+ // Swap rows if needed
1854
+ if (maxRow !== col) {
1855
+ const temp = aug[col];
1856
+ aug[col] = aug[maxRow];
1857
+ aug[maxRow] = temp;
1858
+ }
1859
+ // Check for singular matrix
1860
+ const pivot = aug[col][col];
1861
+ if (Math.abs(pivot) < EPSILON) {
1862
+ return null; // Singular matrix
1863
+ }
1864
+ // Scale pivot row
1865
+ for (let j = 0; j < 2 * n; j++) {
1866
+ aug[col][j] = aug[col][j] / pivot;
1867
+ }
1868
+ // Eliminate column in all other rows
1869
+ for (let row = 0; row < n; row++) {
1870
+ if (row !== col) {
1871
+ const factor = aug[row][col];
1872
+ for (let j = 0; j < 2 * n; j++) {
1873
+ aug[row][j] = aug[row][j] - factor * aug[col][j];
1874
+ }
1875
+ }
1876
+ }
1877
+ }
1878
+ // Extract inverse from augmented matrix
1879
+ const inverse = [];
1880
+ for (let i = 0; i < n; i++) {
1881
+ const row = [];
1882
+ for (let j = 0; j < n; j++) {
1883
+ row.push(aug[i][n + j]);
1884
+ }
1885
+ inverse.push(row);
1886
+ }
1887
+ return {
1888
+ rows: n,
1889
+ columns: n,
1890
+ data: inverse
1891
+ };
1892
+ }
1893
+ /**
1894
+ * Matrix pseudo-inverse (Moore-Penrose)
1895
+ *
1896
+ * Computes the pseudo-inverse of a matrix. For non-singular square matrices,
1897
+ * this returns the same result as inv().
1898
+ *
1899
+ * @param id - A matrix object (can be any shape)
1900
+ * @returns A new matrix containing the pseudo-inverse
1901
+ *
1902
+ * @remarks
1903
+ * Uses the formula: A⁺ = (AᵀA)⁻¹Aᵀ for full column rank matrices,
1904
+ * or Aᵀ(AAᵀ)⁻¹ for full row rank matrices.
1905
+ * For singular matrices, uses iterative refinement approach.
1906
+ *
1907
+ * @example
1908
+ * ```typescript
1909
+ * // Create a 2x2 matrix
1910
+ * const m1 = matrix.new_matrix(2, 2, NaN);
1911
+ * matrix.set(m1, 0, 0, 1);
1912
+ * matrix.set(m1, 0, 1, 2);
1913
+ * matrix.set(m1, 1, 0, 3);
1914
+ * matrix.set(m1, 1, 1, 4);
1915
+ *
1916
+ * const m2 = matrix.pinv(m1);
1917
+ * ```
1918
+ */
1919
+ export function pinv(id) {
1920
+ const m = id.rows;
1921
+ const n = id.columns;
1922
+ if (m === 0 || n === 0) {
1923
+ return new_matrix(n, m, 0);
1924
+ }
1925
+ // For square non-singular matrices, use regular inverse
1926
+ if (m === n) {
1927
+ const inverse = inv(id);
1928
+ if (inverse !== null) {
1929
+ return inverse;
1930
+ }
1931
+ }
1932
+ const At = transpose(id);
1933
+ // If matrix has more rows than columns (m >= n), use (AᵀA)⁻¹Aᵀ
1934
+ if (m >= n) {
1935
+ const AtA = mult(At, id);
1936
+ const AtA_inv = inv(AtA);
1937
+ if (AtA_inv !== null) {
1938
+ return mult(AtA_inv, At);
1939
+ }
1940
+ }
1941
+ // If matrix has more columns than rows (n > m), use Aᵀ(AAᵀ)⁻¹
1942
+ const AAt = mult(id, At);
1943
+ const AAt_inv = inv(AAt);
1944
+ if (AAt_inv !== null) {
1945
+ return mult(At, AAt_inv);
1946
+ }
1947
+ // Fallback: Use regularization for rank-deficient matrices
1948
+ // Add small regularization term: (AᵀA + λI)⁻¹Aᵀ
1949
+ const lambda = 1e-10;
1950
+ const AtA = mult(At, id);
1951
+ // Add regularization
1952
+ for (let i = 0; i < AtA.rows; i++) {
1953
+ AtA.data[i][i] = AtA.data[i][i] + lambda;
1954
+ }
1955
+ const AtA_inv = inv(AtA);
1956
+ if (AtA_inv !== null) {
1957
+ return mult(AtA_inv, At);
1958
+ }
1959
+ // If all else fails, return zero matrix of appropriate dimensions
1960
+ return new_matrix(n, m, 0);
1961
+ }
1962
+ /**
1963
+ * Matrix rank
1964
+ *
1965
+ * Calculates the rank of a matrix (number of linearly independent rows/columns)
1966
+ * using Gaussian elimination to row echelon form.
1967
+ *
1968
+ * @param id - A matrix object
1969
+ * @returns The rank of the matrix
1970
+ *
1971
+ * @remarks
1972
+ * Uses row reduction with partial pivoting.
1973
+ * Time complexity: O(n³)
1974
+ *
1975
+ * @example
1976
+ * ```typescript
1977
+ * // Create a 2x2 matrix
1978
+ * const m1 = matrix.new_matrix(2, 2, NaN);
1979
+ * matrix.set(m1, 0, 0, 1);
1980
+ * matrix.set(m1, 0, 1, 2);
1981
+ * matrix.set(m1, 1, 0, 3);
1982
+ * matrix.set(m1, 1, 1, 4);
1983
+ *
1984
+ * const r = matrix.rank(m1); // Returns: 2
1985
+ * ```
1986
+ */
1987
+ export function rank(id) {
1988
+ if (id.rows === 0 || id.columns === 0) {
1989
+ return 0;
1990
+ }
1991
+ // Make a copy to work with
1992
+ const a = id.data.map(row => [...row]);
1993
+ const m = id.rows;
1994
+ const n = id.columns;
1995
+ let r = 0; // Current rank (and current pivot row)
1996
+ for (let col = 0; col < n && r < m; col++) {
1997
+ // Find pivot
1998
+ let maxRow = r;
1999
+ let maxVal = Math.abs(a[r][col]);
2000
+ for (let row = r + 1; row < m; row++) {
2001
+ const absVal = Math.abs(a[row][col]);
2002
+ if (absVal > maxVal) {
2003
+ maxVal = absVal;
2004
+ maxRow = row;
2005
+ }
2006
+ }
2007
+ // Skip column if all values below are effectively zero
2008
+ if (maxVal < EPSILON) {
2009
+ continue;
2010
+ }
2011
+ // Swap rows if needed
2012
+ if (maxRow !== r) {
2013
+ const temp = a[r];
2014
+ a[r] = a[maxRow];
2015
+ a[maxRow] = temp;
2016
+ }
2017
+ // Eliminate below pivot
2018
+ const pivot = a[r][col];
2019
+ for (let row = r + 1; row < m; row++) {
2020
+ const factor = a[row][col] / pivot;
2021
+ for (let j = col; j < n; j++) {
2022
+ a[row][j] = a[row][j] - factor * a[r][j];
2023
+ }
2024
+ }
2025
+ r++;
2026
+ }
2027
+ return r;
2028
+ }
2029
+ /**
2030
+ * Matrix eigenvalues
2031
+ *
2032
+ * Computes the eigenvalues of a square matrix using the QR algorithm.
2033
+ *
2034
+ * @param id - A matrix object (must be square)
2035
+ * @returns An array containing the eigenvalues
2036
+ *
2037
+ * @remarks
2038
+ * Uses the Implicit QL Algorithm with shifts.
2039
+ * For non-symmetric matrices, only real eigenvalues are returned accurately.
2040
+ * Complex eigenvalues return their real part for 2x2 matrices.
2041
+ * Time complexity: O(n³) per iteration, typically converges in O(n) iterations.
2042
+ *
2043
+ * @example
2044
+ * ```typescript
2045
+ * // Create a 2x2 matrix
2046
+ * const m1 = matrix.new_matrix(2, 2, NaN);
2047
+ * matrix.set(m1, 0, 0, 2);
2048
+ * matrix.set(m1, 0, 1, 4);
2049
+ * matrix.set(m1, 1, 0, 6);
2050
+ * matrix.set(m1, 1, 1, 8);
2051
+ *
2052
+ * const ev = matrix.eigenvalues(m1); // Returns eigenvalues
2053
+ * ```
2054
+ */
2055
+ export function eigenvalues(id) {
2056
+ if (!is_square(id)) {
2057
+ throw new Error(`Matrix must be square for eigenvalue calculation: ${id.rows}x${id.columns}`);
2058
+ }
2059
+ const n = id.rows;
2060
+ if (n === 0) {
2061
+ return [];
2062
+ }
2063
+ if (n === 1) {
2064
+ return [id.data[0][0]];
2065
+ }
2066
+ // For 2x2 matrices, use quadratic formula
2067
+ if (n === 2) {
2068
+ const a = id.data[0][0];
2069
+ const b = id.data[0][1];
2070
+ const c = id.data[1][0];
2071
+ const d = id.data[1][1];
2072
+ // Characteristic polynomial: λ² - (a+d)λ + (ad-bc) = 0
2073
+ const trace = a + d;
2074
+ const determinant = a * d - b * c;
2075
+ const discriminant = trace * trace - 4 * determinant;
2076
+ if (discriminant >= 0) {
2077
+ const sqrtDisc = Math.sqrt(discriminant);
2078
+ return [(trace + sqrtDisc) / 2, (trace - sqrtDisc) / 2];
2079
+ }
2080
+ else {
2081
+ // Complex eigenvalues - return real parts
2082
+ return [trace / 2, trace / 2];
2083
+ }
2084
+ }
2085
+ // For larger matrices, use QR algorithm
2086
+ // First, reduce to Hessenberg form (more efficient for QR)
2087
+ const h = toHessenberg(id);
2088
+ const result = qrAlgorithm(h, 100); // Max 100 iterations
2089
+ return result;
2090
+ }
2091
+ /**
2092
+ * Helper: Convert matrix to upper Hessenberg form
2093
+ */
2094
+ function toHessenberg(m) {
2095
+ const n = m.rows;
2096
+ const h = m.data.map(row => [...row]);
2097
+ for (let k = 0; k < n - 2; k++) {
2098
+ // Find the largest element in column k below diagonal
2099
+ let maxVal = 0;
2100
+ for (let i = k + 1; i < n; i++) {
2101
+ maxVal = Math.max(maxVal, Math.abs(h[i][k]));
2102
+ }
2103
+ if (maxVal < EPSILON)
2104
+ continue;
2105
+ // Compute Householder vector
2106
+ let sigma = 0;
2107
+ for (let i = k + 1; i < n; i++) {
2108
+ sigma += h[i][k] * h[i][k];
2109
+ }
2110
+ sigma = Math.sqrt(sigma);
2111
+ if (h[k + 1][k] < 0)
2112
+ sigma = -sigma;
2113
+ const u = new Array(n).fill(0);
2114
+ u[k + 1] = h[k + 1][k] + sigma;
2115
+ for (let i = k + 2; i < n; i++) {
2116
+ u[i] = h[i][k];
2117
+ }
2118
+ let uTu = 0;
2119
+ for (let i = k + 1; i < n; i++) {
2120
+ uTu += u[i] * u[i];
2121
+ }
2122
+ if (uTu < EPSILON)
2123
+ continue;
2124
+ // Apply H = I - 2*u*u'/u'u from left and right
2125
+ // H * A
2126
+ for (let j = k; j < n; j++) {
2127
+ let dot = 0;
2128
+ for (let i = k + 1; i < n; i++) {
2129
+ dot += u[i] * h[i][j];
2130
+ }
2131
+ const factor = 2 * dot / uTu;
2132
+ for (let i = k + 1; i < n; i++) {
2133
+ h[i][j] = h[i][j] - factor * u[i];
2134
+ }
2135
+ }
2136
+ // A * H
2137
+ for (let i = 0; i < n; i++) {
2138
+ let dot = 0;
2139
+ for (let j = k + 1; j < n; j++) {
2140
+ dot += h[i][j] * u[j];
2141
+ }
2142
+ const factor = 2 * dot / uTu;
2143
+ for (let j = k + 1; j < n; j++) {
2144
+ h[i][j] = h[i][j] - factor * u[j];
2145
+ }
2146
+ }
2147
+ }
2148
+ return { rows: n, columns: n, data: h };
2149
+ }
2150
+ /**
2151
+ * Helper: QR algorithm for eigenvalues
2152
+ */
2153
+ function qrAlgorithm(h, maxIter) {
2154
+ const n = h.rows;
2155
+ const a = h.data.map(row => [...row]);
2156
+ const eigenvals = [];
2157
+ let remaining = n;
2158
+ for (let iter = 0; iter < maxIter && remaining > 1; iter++) {
2159
+ // Check for convergence (subdiagonal element near zero)
2160
+ let converged = false;
2161
+ for (let i = remaining - 1; i >= 1; i--) {
2162
+ if (Math.abs(a[i][i - 1]) < EPSILON * (Math.abs(a[i - 1][i - 1]) + Math.abs(a[i][i]))) {
2163
+ a[i][i - 1] = 0;
2164
+ if (i === remaining - 1) {
2165
+ eigenvals.push(a[remaining - 1][remaining - 1]);
2166
+ remaining--;
2167
+ converged = true;
2168
+ break;
2169
+ }
2170
+ }
2171
+ }
2172
+ if (converged)
2173
+ continue;
2174
+ if (remaining <= 1)
2175
+ break;
2176
+ // Wilkinson shift
2177
+ const d = (a[remaining - 2][remaining - 2] - a[remaining - 1][remaining - 1]) / 2;
2178
+ const sign = d >= 0 ? 1 : -1;
2179
+ const mu = a[remaining - 1][remaining - 1] -
2180
+ sign * a[remaining - 1][remaining - 2] * a[remaining - 1][remaining - 2] /
2181
+ (Math.abs(d) + Math.sqrt(d * d + a[remaining - 1][remaining - 2] * a[remaining - 1][remaining - 2]));
2182
+ // QR step with shift
2183
+ let x = a[0][0] - mu;
2184
+ let z = a[1][0];
2185
+ for (let k = 0; k < remaining - 1; k++) {
2186
+ // Givens rotation
2187
+ let r = Math.sqrt(x * x + z * z);
2188
+ if (r < EPSILON) {
2189
+ r = EPSILON;
2190
+ }
2191
+ const c = x / r;
2192
+ const s = z / r;
2193
+ // Apply rotation from left
2194
+ for (let j = Math.max(0, k - 1); j < remaining; j++) {
2195
+ const temp = c * a[k][j] + s * a[k + 1][j];
2196
+ a[k + 1][j] = -s * a[k][j] + c * a[k + 1][j];
2197
+ a[k][j] = temp;
2198
+ }
2199
+ // Apply rotation from right
2200
+ for (let i = 0; i < Math.min(k + 3, remaining); i++) {
2201
+ const temp = c * a[i][k] + s * a[i][k + 1];
2202
+ a[i][k + 1] = -s * a[i][k] + c * a[i][k + 1];
2203
+ a[i][k] = temp;
2204
+ }
2205
+ if (k < remaining - 2) {
2206
+ x = a[k + 1][k];
2207
+ z = a[k + 2][k];
2208
+ }
2209
+ }
2210
+ }
2211
+ // Extract remaining eigenvalues from diagonal
2212
+ for (let i = 0; i < remaining; i++) {
2213
+ eigenvals.push(a[i][i]);
2214
+ }
2215
+ // Sort eigenvalues in descending order by absolute value
2216
+ eigenvals.sort((a, b) => Math.abs(b) - Math.abs(a));
2217
+ return eigenvals;
2218
+ }
2219
+ /**
2220
+ * Matrix eigenvectors
2221
+ *
2222
+ * Returns a matrix of eigenvectors, where each column is an eigenvector
2223
+ * corresponding to an eigenvalue.
2224
+ *
2225
+ * @param id - A matrix object (must be square)
2226
+ * @returns A new matrix where columns are eigenvectors
2227
+ *
2228
+ * @remarks
2229
+ * Uses inverse iteration method to compute eigenvectors from eigenvalues.
2230
+ * Eigenvectors are normalized to unit length.
2231
+ * Time complexity: O(n³)
2232
+ *
2233
+ * @example
2234
+ * ```typescript
2235
+ * // Create a 2x2 matrix
2236
+ * const m1 = matrix.new_matrix(2, 2, 1);
2237
+ * matrix.set(m1, 0, 0, 2);
2238
+ * matrix.set(m1, 0, 1, 4);
2239
+ * matrix.set(m1, 1, 0, 6);
2240
+ * matrix.set(m1, 1, 1, 8);
2241
+ *
2242
+ * const evecs = matrix.eigenvectors(m1);
2243
+ * // Each column is an eigenvector
2244
+ * ```
2245
+ */
2246
+ export function eigenvectors(id) {
2247
+ if (!is_square(id)) {
2248
+ throw new Error(`Matrix must be square for eigenvector calculation: ${id.rows}x${id.columns}`);
2249
+ }
2250
+ const n = id.rows;
2251
+ if (n === 0) {
2252
+ return new_matrix(0, 0, 0);
2253
+ }
2254
+ // Get eigenvalues first
2255
+ const evals = eigenvalues(id);
2256
+ // For each eigenvalue, compute eigenvector using inverse iteration
2257
+ const vectors = [];
2258
+ for (let i = 0; i < n; i++) {
2259
+ const lambda = evals[i];
2260
+ const vec = inverseIteration(id, lambda);
2261
+ vectors.push(vec);
2262
+ }
2263
+ // Transpose to get eigenvectors as columns
2264
+ const result = [];
2265
+ for (let i = 0; i < n; i++) {
2266
+ const row = [];
2267
+ for (let j = 0; j < n; j++) {
2268
+ row.push(vectors[j][i]);
2269
+ }
2270
+ result.push(row);
2271
+ }
2272
+ return {
2273
+ rows: n,
2274
+ columns: n,
2275
+ data: result
2276
+ };
2277
+ }
2278
+ /**
2279
+ * Helper: Inverse iteration for eigenvector computation
2280
+ */
2281
+ function inverseIteration(m, lambda) {
2282
+ const n = m.rows;
2283
+ // Create (A - λI)
2284
+ const shifted = m.data.map((row, i) => row.map((val, j) => i === j ? val - lambda : val));
2285
+ // Add small perturbation to avoid singular matrix
2286
+ for (let i = 0; i < n; i++) {
2287
+ if (Math.abs(shifted[i][i]) < EPSILON) {
2288
+ shifted[i][i] = EPSILON;
2289
+ }
2290
+ }
2291
+ // Initialize random vector
2292
+ let v = new Array(n).fill(1);
2293
+ // Iterate
2294
+ for (let iter = 0; iter < 50; iter++) {
2295
+ // Solve (A - λI) * w = v using LU decomposition
2296
+ const w = solveLinearSystem(shifted, v);
2297
+ // Normalize
2298
+ let norm = 0;
2299
+ for (let i = 0; i < n; i++) {
2300
+ norm += w[i] * w[i];
2301
+ }
2302
+ norm = Math.sqrt(norm);
2303
+ if (norm < EPSILON) {
2304
+ return v;
2305
+ }
2306
+ const newV = [];
2307
+ for (let i = 0; i < n; i++) {
2308
+ newV.push(w[i] / norm);
2309
+ }
2310
+ // Check convergence
2311
+ let diff = 0;
2312
+ for (let i = 0; i < n; i++) {
2313
+ diff += Math.abs(Math.abs(newV[i]) - Math.abs(v[i]));
2314
+ }
2315
+ v = newV;
2316
+ if (diff < EPSILON) {
2317
+ break;
2318
+ }
2319
+ }
2320
+ return v;
2321
+ }
2322
+ /**
2323
+ * Helper: Solve linear system Ax = b using Gaussian elimination
2324
+ */
2325
+ function solveLinearSystem(a, b) {
2326
+ const n = a.length;
2327
+ // Create augmented matrix
2328
+ const aug = a.map((row, i) => [...row, b[i]]);
2329
+ // Forward elimination with partial pivoting
2330
+ for (let col = 0; col < n; col++) {
2331
+ // Find pivot
2332
+ let maxRow = col;
2333
+ let maxVal = Math.abs(aug[col][col]);
2334
+ for (let row = col + 1; row < n; row++) {
2335
+ const absVal = Math.abs(aug[row][col]);
2336
+ if (absVal > maxVal) {
2337
+ maxVal = absVal;
2338
+ maxRow = row;
2339
+ }
2340
+ }
2341
+ // Swap rows
2342
+ if (maxRow !== col) {
2343
+ const temp = aug[col];
2344
+ aug[col] = aug[maxRow];
2345
+ aug[maxRow] = temp;
2346
+ }
2347
+ const pivot = aug[col][col];
2348
+ if (Math.abs(pivot) < EPSILON) {
2349
+ continue;
2350
+ }
2351
+ // Eliminate
2352
+ for (let row = col + 1; row < n; row++) {
2353
+ const factor = aug[row][col] / pivot;
2354
+ for (let j = col; j <= n; j++) {
2355
+ aug[row][j] = aug[row][j] - factor * aug[col][j];
2356
+ }
2357
+ }
2358
+ }
2359
+ // Back substitution
2360
+ const x = new Array(n).fill(0);
2361
+ for (let i = n - 1; i >= 0; i--) {
2362
+ let sum = aug[i][n];
2363
+ for (let j = i + 1; j < n; j++) {
2364
+ sum -= aug[i][j] * x[j];
2365
+ }
2366
+ const diag = aug[i][i];
2367
+ x[i] = Math.abs(diag) < EPSILON ? 0 : sum / diag;
2368
+ }
2369
+ return x;
2370
+ }
2371
+ /**
2372
+ * Kronecker product
2373
+ *
2374
+ * Computes the Kronecker (tensor) product of two matrices.
2375
+ * Each element of id1 is multiplied by the entire id2 matrix.
2376
+ *
2377
+ * @param id1 - First matrix object
2378
+ * @param id2 - Second matrix object
2379
+ * @returns A new matrix containing the Kronecker product
2380
+ *
2381
+ * @remarks
2382
+ * Result size: (m₁×m₂) rows by (n₁×n₂) columns.
2383
+ * Time complexity: O(m₁×m₂×n₁×n₂)
2384
+ *
2385
+ * @example
2386
+ * ```typescript
2387
+ * // Create two 2x2 matrices
2388
+ * const m1 = matrix.new_matrix(2, 2, 1);
2389
+ * const m2 = matrix.new_matrix(2, 2, 2);
2390
+ *
2391
+ * const m3 = matrix.kron(m1, m2);
2392
+ * // Result is a 4x4 matrix
2393
+ * ```
2394
+ */
2395
+ export function kron(id1, id2) {
2396
+ const m1 = id1.rows;
2397
+ const n1 = id1.columns;
2398
+ const m2 = id2.rows;
2399
+ const n2 = id2.columns;
2400
+ const resultRows = m1 * m2;
2401
+ const resultCols = n1 * n2;
2402
+ const data = [];
2403
+ for (let i = 0; i < resultRows; i++) {
2404
+ data.push(new Array(resultCols).fill(0));
2405
+ }
2406
+ for (let i1 = 0; i1 < m1; i1++) {
2407
+ for (let j1 = 0; j1 < n1; j1++) {
2408
+ const a = id1.data[i1][j1];
2409
+ for (let i2 = 0; i2 < m2; i2++) {
2410
+ for (let j2 = 0; j2 < n2; j2++) {
2411
+ const row = i1 * m2 + i2;
2412
+ const col = j1 * n2 + j2;
2413
+ data[row][col] = a * id2.data[i2][j2];
2414
+ }
2415
+ }
2416
+ }
2417
+ }
2418
+ return {
2419
+ rows: resultRows,
2420
+ columns: resultCols,
2421
+ data
2422
+ };
2423
+ }
2424
+ /**
2425
+ * Create matrix of user-defined type
2426
+ *
2427
+ * Creates a new matrix that can hold user-defined types.
2428
+ * This is a placeholder that functions identically to new_matrix() for now,
2429
+ * as JavaScript doesn't have the same type system as PineScript.
2430
+ *
2431
+ * @param rows - Initial row count
2432
+ * @param columns - Initial column count
2433
+ * @param initial_value - Initial value for all elements
2434
+ * @returns A new matrix object
2435
+ *
2436
+ * @remarks
2437
+ * In PineScript, this is used for matrices containing user-defined types (UDTs).
2438
+ * In JavaScript, this behaves the same as new_matrix() since type handling
2439
+ * is done at runtime.
2440
+ *
2441
+ * @example
2442
+ * ```typescript
2443
+ * // Create a 2x2 matrix that could hold any type
2444
+ * const m = matrix.newtype(2, 2, { name: 'default', value: 0 });
2445
+ * ```
2446
+ */
2447
+ export function newtype(rows = 0, columns = 0, initial_value) {
2448
+ return new_matrix(rows, columns, initial_value);
2449
+ }
2450
+ //# sourceMappingURL=index.js.map