PageRenderTime 62ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 1ms

/libreoffice-3.6.0.2/binfilter/bf_sc/source/core/tool/sc_interpr5.cxx

#
C++ | 4058 lines | 3932 code | 64 blank | 62 comment | 915 complexity | c9a4ec24175cae2fb65466adfd8f45bd MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, AGPL-1.0, BSD-3-Clause-No-Nuclear-License-2014, GPL-3.0, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /*************************************************************************
  3. *
  4. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  5. *
  6. * Copyright 2000, 2010 Oracle and/or its affiliates.
  7. *
  8. * OpenOffice.org - a multi-platform office productivity suite
  9. *
  10. * This file is part of OpenOffice.org.
  11. *
  12. * OpenOffice.org is free software: you can redistribute it and/or modify
  13. * it under the terms of the GNU Lesser General Public License version 3
  14. * only, as published by the Free Software Foundation.
  15. *
  16. * OpenOffice.org is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU Lesser General Public License version 3 for more details
  20. * (a copy is included in the LICENSE file that accompanied this code).
  21. *
  22. * You should have received a copy of the GNU Lesser General Public License
  23. * version 3 along with OpenOffice.org. If not, see
  24. * <http://www.openoffice.org/license.html>
  25. * for a copy of the LGPLv3 License.
  26. *
  27. ************************************************************************/
  28. #ifdef _MSC_VER
  29. #pragma hdrstop
  30. #endif
  31. #include <string.h>
  32. #include <bf_svtools/zforlist.hxx>
  33. #include "interpre.hxx"
  34. #include "dociter.hxx"
  35. #include "scmatrix.hxx"
  36. #include "globstr.hrc"
  37. namespace binfilter {
  38. // STATIC DATA -----------------------------------------------------------
  39. #define SCdEpsilon 1.0E-7
  40. // -----------------------------------------------------------------------
  41. double ScInterpreter::ScGetGGT(double fx, double fy)
  42. {
  43. if (fy == 0.0 || fx == 0.0)
  44. {
  45. SetError(errIllegalArgument);
  46. return 1.0;
  47. }
  48. else
  49. {
  50. double fz = fmod(fx, fy);
  51. while (fz > 0.0)
  52. {
  53. fx = fy;
  54. fy = fz;
  55. fz = fmod(fx, fy);
  56. }
  57. return fy;
  58. }
  59. }
  60. void ScInterpreter::ScGGT()
  61. {
  62. BYTE nParamCount = GetByte();
  63. if ( MustHaveParamCountMin( nParamCount, 1 ) )
  64. {
  65. double fSign = 1.0;
  66. double fx, fy = 0.0;
  67. switch (GetStackType())
  68. {
  69. case svDouble :
  70. case svString:
  71. case svSingleRef:
  72. {
  73. fy = GetDouble();
  74. if (fy < 0.0)
  75. {
  76. fy *= -1.0;
  77. fSign *= -1.0;
  78. }
  79. }
  80. break;
  81. case svDoubleRef :
  82. {
  83. ScRange aRange;
  84. USHORT nErr = 0;
  85. PopDoubleRef( aRange );
  86. double nCellVal;
  87. ScValueIterator aValIter(pDok, aRange, glSubTotal);
  88. if (aValIter.GetFirst(nCellVal, nErr))
  89. {
  90. fy = nCellVal;
  91. if (fy < 0.0)
  92. {
  93. fy *= -1.0;
  94. fSign *= -1.0;
  95. }
  96. while (nErr == 0 && aValIter.GetNext(nCellVal, nErr))
  97. {
  98. fx = nCellVal;
  99. if (fx < 0.0)
  100. {
  101. fx *= -1.0;
  102. fSign *= -1.0;
  103. }
  104. fy = ScGetGGT(fx, fy);
  105. }
  106. SetError(nErr);
  107. }
  108. else
  109. SetError(errIllegalArgument);
  110. }
  111. break;
  112. case svMatrix :
  113. {
  114. ScMatrix* pMat = PopMatrix();
  115. if (pMat)
  116. {
  117. USHORT nC, nR;
  118. pMat->GetDimensions(nC, nR);
  119. if (nC == 0 || nR == 0)
  120. SetError(errIllegalArgument);
  121. else
  122. {
  123. if (!pMat->IsValue(0))
  124. {
  125. SetIllegalArgument();
  126. return;
  127. }
  128. fy = pMat->GetDouble(0);
  129. if (fy < 0.0)
  130. {
  131. fy *= -1.0;
  132. fSign *= -1.0;
  133. }
  134. ULONG nCount = (ULONG) nC * nR;
  135. for ( ULONG j = 1; j < nCount; j++ )
  136. {
  137. if (!pMat->IsValue(j))
  138. {
  139. SetIllegalArgument();
  140. return;
  141. }
  142. fx = pMat->GetDouble(j);
  143. if (fx < 0.0)
  144. {
  145. fx *= -1.0;
  146. fSign *= -1.0;
  147. }
  148. fy = ScGetGGT(fx, fy);
  149. }
  150. }
  151. }
  152. }
  153. break;
  154. default : SetError(errIllegalParameter); break;
  155. }
  156. ScRange aRange;
  157. for (short i = 0; i < (short) nParamCount - 1; i++)
  158. {
  159. switch (GetStackType())
  160. {
  161. case svDouble :
  162. case svString:
  163. case svSingleRef:
  164. {
  165. fx = GetDouble();
  166. if (fx < 0.0)
  167. {
  168. fx *= -1.0;
  169. fSign *= -1.0;
  170. }
  171. fy = ScGetGGT(fx, fy);
  172. }
  173. break;
  174. case svDoubleRef :
  175. {
  176. USHORT nErr = 0;
  177. PopDoubleRef( aRange );
  178. double nCellVal;
  179. ScValueIterator aValIter(pDok, aRange, glSubTotal);
  180. if (aValIter.GetFirst(nCellVal, nErr))
  181. {
  182. fx = nCellVal;
  183. if (fx < 0.0)
  184. {
  185. fx *= -1.0;
  186. fSign *= -1.0;
  187. }
  188. fy = ScGetGGT(fx, fy);
  189. while (nErr == 0 && aValIter.GetNext(nCellVal, nErr))
  190. {
  191. fx = nCellVal;
  192. if (fx < 0.0)
  193. {
  194. fx *= -1.0;
  195. fSign *= -1.0;
  196. }
  197. fy = ScGetGGT(fx, fy);
  198. }
  199. SetError(nErr);
  200. }
  201. else
  202. SetError(errIllegalArgument);
  203. }
  204. break;
  205. case svMatrix :
  206. {
  207. ScMatrix* pMat = PopMatrix();
  208. if (pMat)
  209. {
  210. USHORT nC, nR;
  211. pMat->GetDimensions(nC, nR);
  212. if (nC == 0 || nR == 0)
  213. SetError(errIllegalArgument);
  214. else
  215. {
  216. if (!pMat->IsValue(0))
  217. {
  218. SetIllegalArgument();
  219. return;
  220. }
  221. fx = pMat->GetDouble(0);
  222. if (fx < 0.0)
  223. {
  224. fx *= -1.0;
  225. fSign *= -1.0;
  226. }
  227. fy = ScGetGGT(fx, fy);
  228. ULONG nCount = (ULONG) nC * nR;
  229. for ( ULONG j = 1; j < nCount; j++ )
  230. {
  231. if (!pMat->IsValue(j))
  232. {
  233. SetIllegalArgument();
  234. return;
  235. }
  236. fx = pMat->GetDouble(j);
  237. if (fx < 0.0)
  238. {
  239. fx *= -1.0;
  240. fSign *= -1.0;
  241. }
  242. fy = ScGetGGT(fx, fy);
  243. }
  244. }
  245. }
  246. }
  247. break;
  248. default : SetError(errIllegalParameter); break;
  249. }
  250. }
  251. if (fSign == -1.0)
  252. PushDouble(-fy);
  253. else
  254. PushDouble(fy);
  255. }
  256. }
  257. void ScInterpreter:: ScKGV()
  258. {
  259. BYTE nParamCount = GetByte();
  260. if ( MustHaveParamCountMin( nParamCount, 1 ) )
  261. {
  262. double fSign = 1.0;
  263. double fx, fy = 0.0;
  264. switch (GetStackType())
  265. {
  266. case svDouble :
  267. case svString:
  268. case svSingleRef:
  269. {
  270. fy = GetDouble();
  271. if (fy < 0.0)
  272. {
  273. fy *= -1.0;
  274. fSign *= -1.0;
  275. }
  276. }
  277. break;
  278. case svDoubleRef :
  279. {
  280. ScRange aRange;
  281. USHORT nErr = 0;
  282. PopDoubleRef( aRange );
  283. double nCellVal;
  284. ScValueIterator aValIter(pDok, aRange, glSubTotal);
  285. if (aValIter.GetFirst(nCellVal, nErr))
  286. {
  287. fy = nCellVal;
  288. if (fy < 0.0)
  289. {
  290. fy *= -1.0;
  291. fSign *= -1.0;
  292. }
  293. while (nErr == 0 && aValIter.GetNext(nCellVal, nErr))
  294. {
  295. fx = nCellVal;
  296. if (fx < 0.0)
  297. {
  298. fx *= -1.0;
  299. fSign *= -1.0;
  300. }
  301. fy = fx * fy / ScGetGGT(fx, fy);
  302. }
  303. SetError(nErr);
  304. }
  305. else
  306. SetError(errIllegalArgument);
  307. }
  308. break;
  309. case svMatrix :
  310. {
  311. ScMatrix* pMat = PopMatrix();
  312. if (pMat)
  313. {
  314. USHORT nC, nR;
  315. pMat->GetDimensions(nC, nR);
  316. if (nC == 0 || nR == 0)
  317. SetError(errIllegalArgument);
  318. else
  319. {
  320. if (!pMat->IsValue(0))
  321. {
  322. SetIllegalArgument();
  323. return;
  324. }
  325. fy = pMat->GetDouble(0);
  326. if (fy < 0.0)
  327. {
  328. fy *= -1.0;
  329. fSign *= -1.0;
  330. }
  331. ULONG nCount = (ULONG) nC * nR;
  332. for ( ULONG j = 1; j < nCount; j++ )
  333. {
  334. if (!pMat->IsValue(j))
  335. {
  336. SetIllegalArgument();
  337. return;
  338. }
  339. fx = pMat->GetDouble(j);
  340. if (fx < 0.0)
  341. {
  342. fx *= -1.0;
  343. fSign *= -1.0;
  344. }
  345. fy = fx * fy / ScGetGGT(fx, fy);
  346. }
  347. }
  348. }
  349. }
  350. break;
  351. default : SetError(errIllegalParameter); break;
  352. }
  353. ScRange aRange;
  354. for (short i = 0; i < (short) nParamCount - 1; i++)
  355. {
  356. switch (GetStackType())
  357. {
  358. case svDouble :
  359. case svString:
  360. case svSingleRef:
  361. {
  362. fx = GetDouble();
  363. if (fx < 0.0)
  364. {
  365. fx *= -1.0;
  366. fSign *= -1.0;
  367. }
  368. fy = fx * fy / ScGetGGT(fx, fy);
  369. }
  370. break;
  371. case svDoubleRef :
  372. {
  373. USHORT nErr = 0;
  374. PopDoubleRef( aRange );
  375. double nCellVal;
  376. ScValueIterator aValIter(pDok, aRange, glSubTotal);
  377. if (aValIter.GetFirst(nCellVal, nErr))
  378. {
  379. fx = nCellVal;
  380. if (fx < 0.0)
  381. {
  382. fx *= -1.0;
  383. fSign *= -1.0;
  384. }
  385. fy = fx * fy / ScGetGGT(fx, fy);
  386. while (nErr == 0 && aValIter.GetNext(nCellVal, nErr))
  387. {
  388. fx = nCellVal;
  389. if (fx < 0.0)
  390. {
  391. fx *= -1.0;
  392. fSign *= -1.0;
  393. }
  394. fy = fx * fy / ScGetGGT(fx, fy);
  395. }
  396. SetError(nErr);
  397. }
  398. else
  399. SetError(errIllegalArgument);
  400. }
  401. break;
  402. case svMatrix :
  403. {
  404. ScMatrix* pMat = PopMatrix();
  405. if (pMat)
  406. {
  407. USHORT nC, nR;
  408. pMat->GetDimensions(nC, nR);
  409. if (nC == 0 || nR == 0)
  410. SetError(errIllegalArgument);
  411. else
  412. {
  413. if (!pMat->IsValue(0))
  414. {
  415. SetIllegalArgument();
  416. return;
  417. }
  418. fx = pMat->GetDouble(0);
  419. if (fx < 0.0)
  420. {
  421. fx *= -1.0;
  422. fSign *= -1.0;
  423. }
  424. fy = fx * fy / ScGetGGT(fx, fy);
  425. ULONG nCount = (ULONG) nC * nR;
  426. for ( ULONG j = 1; j < nCount; j++ )
  427. {
  428. if (!pMat->IsValue(j))
  429. {
  430. SetIllegalArgument();
  431. return;
  432. }
  433. fx = pMat->GetDouble(j);
  434. if (fx < 0.0)
  435. {
  436. fx *= -1.0;
  437. fSign *= -1.0;
  438. }
  439. fy = fx * fy / ScGetGGT(fx, fy);
  440. }
  441. }
  442. }
  443. }
  444. break;
  445. default : SetError(errIllegalParameter); break;
  446. }
  447. }
  448. if (fSign == -1.0)
  449. PushDouble(-fy);
  450. else
  451. PushDouble(fy);
  452. }
  453. }
  454. /*N*/ ScMatrix* ScInterpreter::GetNewMat(USHORT nC, USHORT nR, USHORT& nMatInd)
  455. /*N*/ {
  456. /*N*/ if (nMatCount == MAX_ANZ_MAT)
  457. /*N*/ {
  458. /*N*/ OSL_FAIL("ScInterpreter::GetNewMat: Matrixueberlauf");
  459. /*N*/ SetError(errCodeOverflow);
  460. /*N*/ nMatInd = MAX_ANZ_MAT;
  461. /*N*/ return NULL;
  462. /*N*/ }
  463. /*N*/ else
  464. /*N*/ {
  465. /*N*/ if (!bMatDel) // beim ersten Mal
  466. /*N*/ {
  467. /*N*/ ppTempMatArray = new ScMatrix* [MAX_ANZ_MAT];
  468. /*N*/ for (USHORT i = 0; i < MAX_ANZ_MAT; i++)
  469. /*N*/ ppTempMatArray[i] = NULL;
  470. /*N*/ bMatDel = TRUE;
  471. /*N*/ }
  472. /*N*/ ppTempMatArray[nMatCount] = new ScMatrix(nC, nR);
  473. /*N*/ nMatInd = nMatCount++;
  474. /*N*/ return ppTempMatArray[nMatInd];
  475. /*N*/ }
  476. /*N*/ }
  477. /*N*/ void ScInterpreter::ResetNewMat(USHORT nIndex)
  478. /*N*/ {
  479. /*N*/ if (nIndex < MAX_ANZ_MAT)
  480. /*N*/ {
  481. /*N*/ ppTempMatArray[nIndex] = NULL;
  482. /*N*/ if (nIndex == nMatCount - 1)
  483. /*N*/ nMatCount--;
  484. /*N*/ }
  485. /*N*/ }
  486. /*N*/ ScMatrix* ScInterpreter::GetMatrix(USHORT& nMatInd)
  487. /*N*/ {
  488. /*N*/ ScMatrix* pMat = NULL;
  489. /*N*/ switch (GetStackType())
  490. /*N*/ {
  491. /*?*/ case svSingleRef :
  492. /*?*/ {
  493. /*?*/ ScAddress aAdr;
  494. /*?*/ PopSingleRef( aAdr );
  495. /*?*/ pMat = GetNewMat(1, 1, nMatInd);
  496. /*?*/ if (pMat)
  497. /*?*/ {
  498. /*?*/ ScBaseCell* pCell = GetCell( aAdr );
  499. /*?*/ if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE )
  500. /*?*/ {
  501. /*?*/ if (HasCellValueData(pCell))
  502. /*?*/ pMat->PutDouble(GetCellValue(aAdr, pCell), 0);
  503. /*?*/ else
  504. /*?*/ {
  505. /*?*/ String aStr;
  506. /*?*/ GetCellString(aStr, pCell);
  507. /*?*/ pMat->PutString(aStr, 0);
  508. /*?*/ }
  509. /*?*/ }
  510. /*?*/ else
  511. /*?*/ pMat->PutEmpty( 0 );
  512. /*?*/ }
  513. /*?*/ else
  514. /*?*/ SetError(errCodeOverflow);
  515. /*?*/ }
  516. /*?*/ break;
  517. /*N*/ case svDoubleRef:
  518. /*N*/ {
  519. /*N*/ USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2;
  520. /*N*/ PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
  521. /*N*/ if (nTab1 == nTab2)
  522. /*N*/ {
  523. /*N*/ USHORT i, j;
  524. /*N*/ if ( (ULONG) (nRow2 - nRow1 + 1) * (nCol2 - nCol1 + 1) >
  525. /*N*/ ScMatrix::GetElementsMax() )
  526. /*N*/ SetError(errStackOverflow);
  527. /*N*/ else
  528. /*N*/ {
  529. /*N*/ pMat = GetNewMat(nCol2 - nCol1 + 1, nRow2 - nRow1 + 1, nMatInd);
  530. /*N*/ if (pMat)
  531. /*N*/ {
  532. /*N*/ ScAddress aAdr( nCol1, nRow1, nTab1 );
  533. /*N*/ for (i = nRow1; i <= nRow2; i++)
  534. /*N*/ {
  535. /*N*/ aAdr.SetRow( i );
  536. /*N*/ for (j = nCol1; j <= nCol2; j++)
  537. /*N*/ {
  538. /*N*/ aAdr.SetCol( j );
  539. /*N*/ ScBaseCell* pCell = GetCell( aAdr );
  540. /*N*/ if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE )
  541. /*N*/ {
  542. /*N*/ if (HasCellValueData(pCell))
  543. /*N*/ pMat->PutDouble(
  544. /*N*/ GetCellValue( aAdr, pCell ),
  545. /*N*/ j-nCol1, i-nRow1);
  546. /*N*/ else
  547. /*N*/ {
  548. /*?*/ String aStr;
  549. /*?*/ GetCellString(aStr, pCell);
  550. /*?*/ pMat->PutString(aStr, j-nCol1, i-nRow1);
  551. /*N*/ }
  552. /*N*/ }
  553. /*N*/ else
  554. /*?*/ pMat->PutEmpty( j-nCol1, i-nRow1 );
  555. /*N*/ }
  556. /*N*/ }
  557. /*N*/ }
  558. /*N*/ else
  559. /*N*/ SetError(errCodeOverflow);
  560. /*N*/ }
  561. /*N*/ }
  562. /*N*/ else // keine 2D-Matrix
  563. /*N*/ {
  564. /*N*/ nMatInd = MAX_ANZ_MAT;
  565. /*N*/ SetError(errIllegalParameter);
  566. /*N*/ }
  567. /*N*/ }
  568. /*N*/ break;
  569. /*N*/ case svMatrix:
  570. /*N*/ pMat = PopMatrix();
  571. /*N*/ nMatInd = MAX_ANZ_MAT;
  572. /*N*/ break;
  573. /*?*/ default:
  574. /*?*/ Pop();
  575. /*?*/ nMatInd = MAX_ANZ_MAT;
  576. /*?*/ SetError(errIllegalParameter);
  577. /*?*/ break;
  578. /*N*/ }
  579. /*N*/ return pMat;
  580. /*N*/ }
  581. void ScInterpreter::ScMatValue()
  582. {
  583. if ( MustHaveParamCount( GetByte(), 3 ) )
  584. {
  585. USHORT nR = (USHORT) ::rtl::math::approxFloor(GetDouble()); // 0 bis nAnz - 1
  586. USHORT nC = (USHORT) ::rtl::math::approxFloor(GetDouble()); // 0 bis nAnz - 1
  587. switch (GetStackType())
  588. {
  589. case svSingleRef :
  590. {
  591. ScAddress aAdr;
  592. PopSingleRef( aAdr );
  593. ScBaseCell* pCell = GetCell( aAdr );
  594. if (pCell && pCell->GetCellType() == CELLTYPE_FORMULA)
  595. {
  596. USHORT nErrCode = ((ScFormulaCell*)pCell)->GetErrCode();
  597. if (nErrCode != 0)
  598. {
  599. SetError(nErrCode);
  600. PushInt(0);
  601. }
  602. else
  603. {
  604. ScMatrix* pMat;
  605. ((ScFormulaCell*)pCell)->GetMatrix(&pMat);
  606. if (pMat)
  607. {
  608. USHORT nCl, nRw;
  609. pMat->GetDimensions(nCl, nRw);
  610. if (nC < nCl && nR < nRw)
  611. {
  612. BOOL bIsString;
  613. const MatValue* pMatVal = pMat->Get(nC, nR, bIsString);
  614. if (bIsString)
  615. PushString( pMatVal->GetString() );
  616. else
  617. PushDouble(pMatVal->fVal);
  618. }
  619. else
  620. SetNoValue();
  621. }
  622. else
  623. SetNoValue();
  624. }
  625. }
  626. else
  627. SetIllegalParameter();
  628. }
  629. break;
  630. case svDoubleRef :
  631. {
  632. USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2;
  633. PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
  634. if (nCol2 - nCol1 >= nR && nRow2 - nRow1 >= nC && nTab1 == nTab2)
  635. {
  636. ScAddress aAdr( nCol1 + nR, nRow1 + nC, nTab1 );
  637. ScBaseCell* pCell = GetCell( aAdr );
  638. if (HasCellValueData(pCell))
  639. PushDouble(GetCellValue( aAdr, pCell ));
  640. else
  641. {
  642. String aStr;
  643. GetCellString(aStr, pCell);
  644. PushString(aStr);
  645. }
  646. }
  647. else
  648. SetNoValue();
  649. }
  650. break;
  651. case svMatrix:
  652. {
  653. ScMatrix* pMat = PopMatrix();
  654. if (pMat)
  655. {
  656. USHORT nCl, nRw;
  657. pMat->GetDimensions(nCl, nRw);
  658. if (nC < nCl && nR < nRw)
  659. {
  660. BOOL bIsString;
  661. const MatValue* pMatVal = pMat->Get(nC, nR, bIsString);
  662. if (bIsString)
  663. PushString( pMatVal->GetString() );
  664. else
  665. PushDouble(pMatVal->fVal);
  666. }
  667. else
  668. SetNoValue();
  669. }
  670. else
  671. SetNoValue();
  672. }
  673. break;
  674. default:
  675. Pop();
  676. SetIllegalParameter();
  677. break;
  678. }
  679. }
  680. }
  681. void ScInterpreter::ScEMat()
  682. {
  683. if ( MustHaveParamCount( GetByte(), 1 ) )
  684. {
  685. ULONG nDim = (ULONG) ::rtl::math::approxFloor(GetDouble());
  686. if ( nDim * nDim > ScMatrix::GetElementsMax() || nDim == 0)
  687. SetIllegalArgument();
  688. else
  689. {
  690. USHORT nMatInd;
  691. ScMatrix* pRMat = GetNewMat((USHORT)nDim, (USHORT)nDim, nMatInd);
  692. if (pRMat)
  693. {
  694. MEMat(pRMat, (USHORT) nDim);
  695. nRetMat = nMatInd;
  696. PushMatrix(pRMat);
  697. }
  698. else
  699. SetError(errStackOverflow);
  700. }
  701. }
  702. }
  703. void ScInterpreter::MEMat(ScMatrix* mM, USHORT n)
  704. {
  705. mM->FillDouble(0.0, 0, 0, n-1, n-1);
  706. for (USHORT i = 0; i < n; i++)
  707. mM->PutDouble(1.0, i, i);
  708. }
  709. void ScInterpreter::MFastMult(ScMatrix* pA, ScMatrix* pB, ScMatrix* pR,
  710. USHORT n, USHORT m, USHORT l)
  711. // Multipliziert n x m Mat a mit m x l Mat b nach Mat r
  712. {
  713. double sum;
  714. for (USHORT i = 0; i < n; i++)
  715. {
  716. for (USHORT j = 0; j < l; j++)
  717. {
  718. sum = 0.0;
  719. for (USHORT k = 0; k < m; k++)
  720. sum += pA->GetDouble(i,k)*pB->GetDouble(k,j);
  721. pR->PutDouble(sum, i, j);
  722. }
  723. }
  724. }
  725. void ScInterpreter::MFastSub(ScMatrix* pA, ScMatrix* pB, ScMatrix* pR,
  726. USHORT n, USHORT m)
  727. // Subtrahiert n x m Mat a - m x l Mat b nach Mat r
  728. {
  729. for (USHORT i = 0; i < n; i++)
  730. {
  731. for (USHORT j = 0; j < m; j++)
  732. pR->PutDouble(pA->GetDouble(i,j) - pB->GetDouble(i,j), i, j);
  733. }
  734. }
  735. void ScInterpreter::MFastTrans(ScMatrix* pA, ScMatrix* pR,
  736. USHORT n, USHORT m)
  737. // Transponiert n x m Mat a nach Mat r
  738. {
  739. for (USHORT i = 0; i < n; i++)
  740. for (USHORT j = 0; j < m; j++)
  741. pR->PutDouble(pA->GetDouble(i, j), j, i);
  742. }
  743. BOOL ScInterpreter::MFastBackSubst(ScMatrix* pA, ScMatrix* pR, USHORT n, BOOL bIsUpper)
  744. // F?hrt R?ckwaertsersetzung der Dreickesmatrix Mat a nach Mat r durch
  745. // 2 Versionen fuer obere (U) oder untere (L- Unit) Dreiecksmatrizen
  746. {
  747. short i, j, k;
  748. double fSum;
  749. if (!bIsUpper) // L-Matrix, immer invertierbar
  750. {
  751. MEMat(pR, n);
  752. for (i = 1; i < (short) n; i++)
  753. {
  754. for (j = 0; j < i; j++)
  755. {
  756. fSum = 0.0;
  757. for (k = 0; k < i; k++)
  758. fSum += pA->GetDouble(i,k) * pR->GetDouble(k,j);
  759. pR->PutDouble(-fSum, i, j);
  760. }
  761. }
  762. }
  763. else // U-Matrix
  764. {
  765. for (i = 0; i < (short) n; i++) // Ist invertierbar?
  766. if (fabs(pA->GetDouble(i,i)) < SCdEpsilon)
  767. return FALSE;
  768. pR->FillDoubleLowerLeft(0.0, n-1); // untere Haelfte
  769. pR->PutDouble(1.0/pA->GetDouble(n-1, n-1), n-1, n-1); // n-1, n-1
  770. for (i = (short) n-2; i >= 0; i--)
  771. {
  772. for (j = (short) n-1; j > i; j--)
  773. {
  774. fSum = 0.0;
  775. for (k = (short) n-1; k > i; k--)
  776. fSum += pA->GetDouble(i, k) * pR->GetDouble(k, j);
  777. pR->PutDouble(-fSum/pA->GetDouble(i, i), i, j);
  778. }
  779. fSum = 0.0; // Hauptdiagonale:
  780. for (k = (short) n-1; k > i; k--)
  781. fSum += pA->GetDouble(i, k) * pR->GetDouble(k, j);
  782. pR->PutDouble((1.0-fSum)/pA->GetDouble(i, i), i, i);
  783. }
  784. }
  785. return TRUE;
  786. }
  787. BOOL ScInterpreter::ScMatLUP(ScMatrix* mA, USHORT m, USHORT p,
  788. ScMatrix* mL, ScMatrix* mU, ScMatrix* mP,
  789. ULONG& rPermutCounter, BOOL& bIsInvertable)
  790. // Returnwert = False <=> Matrixarray voll
  791. // BIsInvertable = False: <= mA hat nicht Rang m
  792. {
  793. USHORT nMatInd1, nMatInd2, nMatInd3, nMatInd4, nMatInd5;
  794. USHORT i, j;
  795. if (m == 1)
  796. {
  797. mL->PutDouble(1.0,0,0);
  798. for (j = 0; j < p; j++)
  799. if (fabs(mA->GetDouble(0, j)) >= SCdEpsilon)
  800. break;
  801. if (j == p)
  802. {
  803. bIsInvertable = FALSE;
  804. return TRUE;
  805. }
  806. MEMat(mP, p);
  807. if (j > 0 && j < p)
  808. {
  809. mP->PutDouble(0.0, 0, 0);
  810. mP->PutDouble(1.0, j, 0);
  811. mP->PutDouble(0.0, j, j);
  812. mP->PutDouble(1.0, 0, j);
  813. rPermutCounter++;
  814. }
  815. MFastMult(mA, mP, mU, m, p, p);
  816. }
  817. else
  818. {
  819. USHORT md2 = m/2;
  820. ScMatrix* mB = GetNewMat(md2, p, nMatInd1);
  821. ScMatrix* mC = GetNewMat(md2, p, nMatInd2);
  822. ScMatrix* mL1 = GetNewMat(md2, md2, nMatInd3);
  823. ScMatrix* mU1 = GetNewMat(md2, p, nMatInd4);
  824. ScMatrix* mP1 = GetNewMat(p, p, nMatInd5);
  825. if (!mB || !mC || !mL1 || !mU1 || !mP1 )
  826. return FALSE;
  827. for (i = 0; i < md2; i++)
  828. {
  829. for (j = 0; j < p; j++)
  830. {
  831. mB->PutDouble(mA->GetDouble(i, j), i, j);
  832. mC->PutDouble(mA->GetDouble(md2+i,j), i, j);
  833. }
  834. }
  835. if (!ScMatLUP(mB, md2, p, mL1, mU1, mP1, rPermutCounter, bIsInvertable))
  836. return FALSE;
  837. if (!bIsInvertable)
  838. {
  839. ResetNewMat(nMatInd5);
  840. ResetNewMat(nMatInd4);
  841. ResetNewMat(nMatInd3);
  842. ResetNewMat(nMatInd2);
  843. ResetNewMat(nMatInd1);
  844. delete mP1;
  845. delete mU1;
  846. delete mL1;
  847. delete mC;
  848. delete mB;
  849. return TRUE;
  850. }
  851. USHORT nMatInd6, nMatInd7, nMatInd8, nMatInd9, nMatInd10;
  852. USHORT nMatInd11, nMatInd12, nMatInd13;
  853. ScMatrix* mE = GetNewMat(md2, md2, nMatInd6);
  854. ScMatrix* mF = GetNewMat(md2, md2, nMatInd7);
  855. ScMatrix* mEInv = GetNewMat(md2, md2, nMatInd8);
  856. ScMatrix* mG = GetNewMat(md2, p, nMatInd9);
  857. ScMatrix* mGs = GetNewMat(md2, p - md2, nMatInd10);
  858. ScMatrix* mU2 = GetNewMat(md2, p - md2, nMatInd11);
  859. ScMatrix* mP2 = GetNewMat(p - md2, p - md2, nMatInd12);
  860. if (!mP2 || !mU2 || !mGs|| !mG || !mEInv || !mF || !mE)
  861. return FALSE;
  862. MFastTrans(mP1, mP, p, p); // mP = mP1 hoch -1
  863. ScMatrix* mD = mB; // mB wird nicht mehr gebraucht
  864. MFastMult(mC, mP, mD, md2, p, p);
  865. for (i = 0; i < md2; i++)
  866. {
  867. for (j = 0; j < md2; j++)
  868. {
  869. mE->PutDouble(mU1->GetDouble(i, j), i, j);
  870. mF->PutDouble(mD->GetDouble(i, j), i, j);
  871. }
  872. }
  873. BOOL bEInvok = MFastBackSubst(mE, mEInv, md2, TRUE); // MeInv = E hoch -1
  874. if (!bEInvok)
  875. {
  876. bIsInvertable = FALSE;
  877. ResetNewMat(nMatInd12);
  878. ResetNewMat(nMatInd11);
  879. ResetNewMat(nMatInd10);
  880. ResetNewMat(nMatInd9);
  881. ResetNewMat(nMatInd8);
  882. ResetNewMat(nMatInd7);
  883. ResetNewMat(nMatInd6);
  884. ResetNewMat(nMatInd5);
  885. ResetNewMat(nMatInd4);
  886. ResetNewMat(nMatInd3);
  887. ResetNewMat(nMatInd2);
  888. ResetNewMat(nMatInd1);
  889. delete mP2;
  890. delete mU2;
  891. delete mGs;
  892. delete mG;
  893. delete mEInv;
  894. delete mF;
  895. delete mE;
  896. delete mP1;
  897. delete mU1;
  898. delete mL1;
  899. delete mC;
  900. delete mB;
  901. return TRUE;
  902. }
  903. ScMatrix* mFEInv = mE; // mE wird nicht mehr gebraucht.
  904. MFastMult(mF, mEInv, mFEInv, md2, md2, md2);
  905. ScMatrix* mFEInvU1 = mC; // mC wird nicht mehr gebraucht
  906. MFastMult(mFEInv, mU1, mFEInvU1, md2, md2, p);
  907. MFastSub(mD, mFEInvU1, mG, md2, p);
  908. for (i = 0; i < md2; i++)
  909. {
  910. for (j = 0; j < p-md2; j++)
  911. mGs->PutDouble(mG->GetDouble(i, md2+j), i, j);
  912. }
  913. ScMatrix* mL2 = mF; // mF wird nicht mehr gebraucht
  914. if (!ScMatLUP(mGs, md2, p - md2, mL2, mU2, mP2, rPermutCounter, bIsInvertable))
  915. return FALSE;
  916. if (!bIsInvertable)
  917. {
  918. ResetNewMat(nMatInd12);
  919. ResetNewMat(nMatInd11);
  920. ResetNewMat(nMatInd10);
  921. ResetNewMat(nMatInd9);
  922. ResetNewMat(nMatInd8);
  923. ResetNewMat(nMatInd7);
  924. ResetNewMat(nMatInd6);
  925. ResetNewMat(nMatInd5);
  926. ResetNewMat(nMatInd4);
  927. ResetNewMat(nMatInd3);
  928. ResetNewMat(nMatInd2);
  929. ResetNewMat(nMatInd1);
  930. delete mP2;
  931. delete mU2;
  932. delete mGs;
  933. delete mG;
  934. delete mEInv;
  935. delete mF;
  936. delete mE;
  937. delete mP1;
  938. delete mU1;
  939. delete mL1;
  940. delete mC;
  941. delete mB;
  942. return TRUE;
  943. }
  944. ScMatrix* mP3 = GetNewMat(p, p, nMatInd13);
  945. if (!mP3)
  946. return FALSE;
  947. MEMat(mP3, p);
  948. for (i = md2; i < p; i++)
  949. {
  950. for (j = md2; j < p; j++)
  951. mP3->PutDouble(mP2->GetDouble(i-md2, j-md2), i, j);
  952. }
  953. MFastMult(mP3, mP1, mP, p, p, p); // Ergebnis P !!
  954. ScMatrix* mP3Inv = mP1; // mP1 wird nicht mehr gebraucht;
  955. MFastTrans(mP3, mP3Inv, p, p);
  956. ScMatrix* mH = mD; // mD wird nicht mehr gebraucht
  957. MFastMult(mU1, mP3Inv, mH, md2, p, p);
  958. MEMat(mL, m); // Ergebnis L :
  959. for (i = 0; i < md2; i++)
  960. {
  961. for (j = 0; j < i; j++)
  962. mL->PutDouble(mL1->GetDouble(i, j), i, j);
  963. }
  964. for (i = md2; i < m; i++)
  965. for (j = md2; j < i; j++)
  966. mL->PutDouble(mL2->GetDouble(i-md2, j-md2), i, j);
  967. for (i = md2; i < m; i++)
  968. for (j = 0; j < md2; j++)
  969. mL->PutDouble(mFEInv->GetDouble(i-md2, j), i, j);
  970. // Ergebnis U:
  971. mU->FillDoubleLowerLeft(0.0, m-1);
  972. for (i = 0; i < md2; i++)
  973. for (j = i; j < p; j++)
  974. mU->PutDouble(mH->GetDouble(i, j), i, j);
  975. for (i = md2; i < m; i++)
  976. for (j = i; j < p; j++)
  977. mU->PutDouble(mU2->GetDouble(i - md2, j - md2), i, j);
  978. ResetNewMat(nMatInd13); // alle wieder freigeben;
  979. ResetNewMat(nMatInd12);
  980. ResetNewMat(nMatInd11);
  981. ResetNewMat(nMatInd10);
  982. ResetNewMat(nMatInd9);
  983. ResetNewMat(nMatInd8);
  984. ResetNewMat(nMatInd7);
  985. ResetNewMat(nMatInd6);
  986. ResetNewMat(nMatInd5);
  987. ResetNewMat(nMatInd4);
  988. ResetNewMat(nMatInd3);
  989. ResetNewMat(nMatInd2);
  990. ResetNewMat(nMatInd1);
  991. delete mP3;
  992. delete mP2;
  993. delete mU2;
  994. delete mGs;
  995. delete mG;
  996. delete mEInv;
  997. delete mF;
  998. delete mE;
  999. delete mP1;
  1000. delete mU1;
  1001. delete mL1;
  1002. delete mC;
  1003. delete mB;
  1004. }
  1005. return TRUE;
  1006. }
  1007. void ScInterpreter::ScMatDet()
  1008. {
  1009. if ( MustHaveParamCount( GetByte(), 1 ) )
  1010. {
  1011. USHORT nMatInd;
  1012. ScMatrix* pMat = GetMatrix(nMatInd);
  1013. if (!pMat)
  1014. {
  1015. SetIllegalParameter();
  1016. return;
  1017. }
  1018. if ( !pMat->IsNumeric() )
  1019. {
  1020. SetNoValue();
  1021. return;
  1022. }
  1023. USHORT nC, nR;
  1024. pMat->GetDimensions(nC, nR);
  1025. if ( nC != nR || nC == 0 || (ULONG) nC * nC > ScMatrix::GetElementsMax() )
  1026. SetIllegalParameter();
  1027. else
  1028. {
  1029. double fVal = log((double)nC) / log(2.0);
  1030. if (fVal - floor(fVal) != 0.0)
  1031. fVal = floor(fVal) + 1.0;
  1032. USHORT nDim = (USHORT) pow(2.0, fVal);
  1033. USHORT nMatInd1, nMatInd2, nMatInd3;
  1034. USHORT nMatInd4 = MAX_ANZ_MAT;
  1035. ScMatrix* pU = GetNewMat(nDim, nDim, nMatInd1);
  1036. ScMatrix* pL = GetNewMat(nDim, nDim, nMatInd2);
  1037. ScMatrix* pP = GetNewMat(nDim, nDim, nMatInd3);
  1038. ScMatrix* pA;
  1039. if (nC == nDim)
  1040. pA = pMat;
  1041. else
  1042. {
  1043. pA = GetNewMat(nDim, nDim, nMatInd4);
  1044. MEMat(pA, nDim);
  1045. for (USHORT i = 0; i < nC; i++)
  1046. for (USHORT j = 0; j < nC; j++)
  1047. {
  1048. pA->PutDouble(pMat->GetDouble(i, j), i, j);
  1049. }
  1050. }
  1051. ULONG nPermutCounter = 0;
  1052. BOOL bIsInvertable = TRUE;
  1053. BOOL bOk = ScMatLUP(pA, nDim, nDim, pL, pU, pP,
  1054. nPermutCounter, bIsInvertable);
  1055. ResetNewMat(nMatInd4);
  1056. ResetNewMat(nMatInd3);
  1057. ResetNewMat(nMatInd2);
  1058. if (nC != nDim)
  1059. delete pA;
  1060. delete pP;
  1061. delete pL;
  1062. if (bOk)
  1063. {
  1064. if (!bIsInvertable)
  1065. PushInt(0);
  1066. else
  1067. {
  1068. double fDet = 1.0;
  1069. for (USHORT i = 0; i < nC; i++)
  1070. fDet *= pU->GetDouble(i, i);
  1071. if (nPermutCounter % 2 != 0)
  1072. fDet *= -1.0;
  1073. PushDouble(fDet);
  1074. }
  1075. }
  1076. else
  1077. {
  1078. SetError(errCodeOverflow);
  1079. PushInt(0);
  1080. }
  1081. ResetNewMat(nMatInd1);
  1082. delete pU;
  1083. }
  1084. }
  1085. }
  1086. void ScInterpreter::ScMatInv()
  1087. {
  1088. if ( MustHaveParamCount( GetByte(), 1 ) )
  1089. {
  1090. USHORT nMatInd;
  1091. ScMatrix* pMat = GetMatrix(nMatInd);
  1092. if (!pMat)
  1093. {
  1094. SetIllegalParameter();
  1095. return;
  1096. }
  1097. if ( !pMat->IsNumeric() )
  1098. {
  1099. SetNoValue();
  1100. return;
  1101. }
  1102. USHORT nC, nR;
  1103. pMat->GetDimensions(nC, nR);
  1104. if ( nC != nR || nC == 0 || (ULONG) nC * nC > ScMatrix::GetElementsMax() )
  1105. SetIllegalParameter();
  1106. else
  1107. {
  1108. double fVal = log((double)nC) / log(2.0);
  1109. if (fVal - floor(fVal) != 0.0)
  1110. fVal = floor(fVal) + 1.0;
  1111. USHORT nDim = (USHORT) pow(2.0, fVal);
  1112. USHORT nMatInd1, nMatInd2, nMatInd3;
  1113. USHORT nMatInd4 = MAX_ANZ_MAT;
  1114. ScMatrix* pU = GetNewMat(nDim, nDim, nMatInd1);
  1115. ScMatrix* pL = GetNewMat(nDim, nDim, nMatInd2);
  1116. ScMatrix* pP = GetNewMat(nDim, nDim, nMatInd3);
  1117. ScMatrix* pA;
  1118. if (nC == nDim)
  1119. pA = pMat;
  1120. else
  1121. {
  1122. pA = GetNewMat(nDim, nDim, nMatInd4);
  1123. MEMat(pA, nDim);
  1124. for (USHORT i = 0; i < nC; i++)
  1125. for (USHORT j = 0; j < nC; j++)
  1126. {
  1127. pA->PutDouble(pMat->GetDouble(i, j), i, j);
  1128. }
  1129. }
  1130. ULONG nPermutCounter = 0;
  1131. BOOL bIsInvertable = TRUE;
  1132. BOOL bOk = ScMatLUP(pA, nDim, nDim, pL, pU, pP,
  1133. nPermutCounter, bIsInvertable);
  1134. if (bOk)
  1135. {
  1136. if (!bIsInvertable)
  1137. SetNoValue();
  1138. else
  1139. {
  1140. USHORT nMatInd5;
  1141. ScMatrix* pUInv = GetNewMat(nDim, nDim, nMatInd5);
  1142. if (!pUInv)
  1143. PushInt(0);
  1144. else
  1145. {
  1146. bOk = MFastBackSubst(pU, pUInv, nDim, TRUE);
  1147. if (!bOk)
  1148. SetNoValue();
  1149. else
  1150. {
  1151. ScMatrix* pPInv = pU;
  1152. MFastTrans(pP, pPInv, nDim, nDim);
  1153. ScMatrix* pPInvUInv = pP;
  1154. MFastMult(pPInv, pUInv, pPInvUInv, nDim, nDim, nDim);
  1155. ScMatrix* pLInv = pPInv;
  1156. MFastBackSubst(pL, pLInv, nDim, FALSE);
  1157. if (nDim == nC)
  1158. MFastMult(pPInvUInv, pLInv, pMat, nDim, nDim, nDim);
  1159. else
  1160. {
  1161. MFastMult(pPInvUInv, pLInv, pL, nDim, nDim, nDim);
  1162. for (USHORT i = 0; i < nC; i++)
  1163. for (USHORT j = 0; j < nC; j++)
  1164. pMat->PutDouble(pL->GetDouble(i, j), i, j);
  1165. }
  1166. PushMatrix(pMat);
  1167. if (nMatInd != MAX_ANZ_MAT) // vorher neue Matrix
  1168. nRetMat = nMatInd; // sonst nRetMat wie vorher
  1169. ResetNewMat(nMatInd5);
  1170. delete pUInv;
  1171. }
  1172. }
  1173. }
  1174. }
  1175. else
  1176. {
  1177. SetError(errCodeOverflow);
  1178. PushInt(0);
  1179. }
  1180. ResetNewMat(nMatInd4);
  1181. ResetNewMat(nMatInd3);
  1182. ResetNewMat(nMatInd2);
  1183. ResetNewMat(nMatInd1);
  1184. if (nC != nDim)
  1185. delete pA;
  1186. delete pP;
  1187. delete pL;
  1188. delete pU;
  1189. }
  1190. }
  1191. }
  1192. void ScInterpreter::ScMatMult()
  1193. {
  1194. if ( MustHaveParamCount( GetByte(), 2 ) )
  1195. {
  1196. USHORT nMatInd1, nMatInd2;
  1197. ScMatrix* pMat2 = GetMatrix(nMatInd2);
  1198. ScMatrix* pMat1 = GetMatrix(nMatInd1);
  1199. ScMatrix* pRMat;
  1200. if (pMat1 && pMat2)
  1201. {
  1202. if ( pMat1->IsNumeric() && pMat2->IsNumeric() )
  1203. {
  1204. USHORT nC1, nR1, nC2, nR2;
  1205. pMat1->GetDimensions(nC1, nR1);
  1206. pMat2->GetDimensions(nC2, nR2);
  1207. if (nC1 != nR2)
  1208. SetIllegalParameter();
  1209. else
  1210. {
  1211. USHORT nMatInd;
  1212. pRMat = GetNewMat(nC2, nR1, nMatInd); // Matrixabsicherung
  1213. if (pRMat)
  1214. {
  1215. double sum;
  1216. for (USHORT i = 0; i < nR1; i++)
  1217. {
  1218. for (USHORT j = 0; j < nC2; j++)
  1219. {
  1220. sum = 0.0;
  1221. for (USHORT k = 0; k < nC1; k++)
  1222. {
  1223. sum += pMat1->GetDouble(k,i)*pMat2->GetDouble(j,k);
  1224. }
  1225. pRMat->PutDouble(sum, j, i);
  1226. }
  1227. }
  1228. PushMatrix(pRMat);
  1229. nRetMat = nMatInd;
  1230. }
  1231. else
  1232. SetNoValue();
  1233. }
  1234. }
  1235. else
  1236. SetNoValue();
  1237. }
  1238. else
  1239. SetIllegalParameter();
  1240. }
  1241. }
  1242. void ScInterpreter::ScMatTrans()
  1243. {
  1244. if ( MustHaveParamCount( GetByte(), 1 ) )
  1245. {
  1246. USHORT nMatInd, nMatInd1;
  1247. ScMatrix* pMat = GetMatrix(nMatInd);
  1248. ScMatrix* pRMat;
  1249. if (pMat)
  1250. {
  1251. USHORT nC, nR;
  1252. pMat->GetDimensions(nC, nR);
  1253. pRMat = GetNewMat(nR, nC, nMatInd1);
  1254. pMat->MatTrans(*pRMat);
  1255. PushMatrix(pRMat);
  1256. nRetMat = nMatInd1;
  1257. }
  1258. else
  1259. SetIllegalParameter();
  1260. }
  1261. }
  1262. /*N*/ ScMatrix* ScInterpreter::MatAdd(ScMatrix* pMat1, ScMatrix* pMat2)
  1263. /*N*/ {
  1264. /*N*/ USHORT nC1, nR1, nC2, nR2, nMinC, nMinR, i, j;
  1265. /*N*/ pMat1->GetDimensions(nC1, nR1);
  1266. /*N*/ pMat2->GetDimensions(nC2, nR2);
  1267. /*N*/ if (nC1 < nC2)
  1268. /*N*/ nMinC = nC1;
  1269. /*N*/ else
  1270. /*N*/ nMinC = nC2;
  1271. /*N*/ if (nR1 < nR2)
  1272. /*N*/ nMinR = nR1;
  1273. /*N*/ else
  1274. /*N*/ nMinR = nR2;
  1275. /*N*/ USHORT nMatInd;
  1276. /*N*/ ScMatrix* pResMat = GetNewMat(nMinC, nMinR, nMatInd);
  1277. /*N*/ if (pResMat)
  1278. /*N*/ {
  1279. /*N*/ for (i = 0; i < nMinC; i++)
  1280. /*N*/ {
  1281. /*N*/ for (j = 0; j < nMinR; j++)
  1282. /*N*/ {
  1283. /*N*/ if (pMat1->IsValueOrEmpty(i,j) && pMat2->IsValueOrEmpty(i,j))
  1284. /*N*/ pResMat->PutDouble( ::rtl::math::approxAdd( pMat1->GetDouble(i,j),
  1285. /*N*/ pMat2->GetDouble(i,j)), i, j);
  1286. /*N*/ else
  1287. /*?*/ pResMat->PutString(ScGlobal::GetRscString(
  1288. /*N*/ STR_NO_VALUE), i, j);
  1289. /*N*/ }
  1290. /*N*/ }
  1291. /*N*/ nRetMat = nMatInd;
  1292. /*N*/ }
  1293. /*N*/ return pResMat;
  1294. /*N*/ }
  1295. ScMatrix* ScInterpreter::MatSub(ScMatrix* pMat1, ScMatrix* pMat2)
  1296. {
  1297. USHORT nC1, nR1, nC2, nR2, nMinC, nMinR, i, j;
  1298. pMat1->GetDimensions(nC1, nR1);
  1299. pMat2->GetDimensions(nC2, nR2);
  1300. if (nC1 < nC2)
  1301. nMinC = nC1;
  1302. else
  1303. nMinC = nC2;
  1304. if (nR1 < nR2)
  1305. nMinR = nR1;
  1306. else
  1307. nMinR = nR2;
  1308. USHORT nMatInd;
  1309. ScMatrix* pResMat = GetNewMat(nMinC, nMinR, nMatInd);
  1310. if (pResMat)
  1311. {
  1312. for (i = 0; i < nMinC; i++)
  1313. {
  1314. for (j = 0; j < nMinR; j++)
  1315. {
  1316. if (pMat1->IsValueOrEmpty(i,j) && pMat2->IsValueOrEmpty(i,j))
  1317. pResMat->PutDouble( ::rtl::math::approxSub( pMat1->GetDouble(i,j),
  1318. pMat2->GetDouble(i,j)), i, j);
  1319. else
  1320. pResMat->PutString(ScGlobal::GetRscString(
  1321. STR_NO_VALUE), i, j);
  1322. }
  1323. }
  1324. nRetMat = nMatInd;
  1325. }
  1326. return pResMat;
  1327. }
  1328. /*N*/ ScMatrix* ScInterpreter::MatMul(ScMatrix* pMat1, ScMatrix* pMat2)
  1329. /*N*/ {
  1330. /*N*/ USHORT nC1, nR1, nC2, nR2, nMinC, nMinR, i, j;
  1331. /*N*/ pMat1->GetDimensions(nC1, nR1);
  1332. /*N*/ pMat2->GetDimensions(nC2, nR2);
  1333. /*N*/ if (nC1 < nC2)
  1334. /*N*/ nMinC = nC1;
  1335. /*N*/ else
  1336. /*N*/ nMinC = nC2;
  1337. /*N*/ if (nR1 < nR2)
  1338. /*N*/ nMinR = nR1;
  1339. /*N*/ else
  1340. /*N*/ nMinR = nR2;
  1341. /*N*/ USHORT nMatInd;
  1342. /*N*/ ScMatrix* pResMat = GetNewMat(nMinC, nMinR, nMatInd);
  1343. /*N*/ if (pResMat)
  1344. /*N*/ {
  1345. /*N*/ for (i = 0; i < nMinC; i++)
  1346. /*N*/ {
  1347. /*N*/ for (j = 0; j < nMinR; j++)
  1348. /*N*/ {
  1349. /*N*/ if (pMat1->IsValueOrEmpty(i,j) && pMat2->IsValueOrEmpty(i,j))
  1350. /*N*/ pResMat->PutDouble(pMat1->GetDouble(i,j) *
  1351. /*N*/ pMat2->GetDouble(i,j), i, j);
  1352. /*N*/ else
  1353. /*?*/ pResMat->PutString(ScGlobal::GetRscString(
  1354. /*N*/ STR_NO_VALUE), i, j);
  1355. /*N*/ }
  1356. /*N*/ }
  1357. /*N*/ nRetMat = nMatInd;
  1358. /*N*/ }
  1359. /*N*/ return pResMat;
  1360. /*N*/ }
  1361. ScMatrix* ScInterpreter::MatDiv(ScMatrix* pMat1, ScMatrix* pMat2)
  1362. {
  1363. USHORT nC1, nR1, nC2, nR2, nMinC, nMinR, i, j;
  1364. pMat1->GetDimensions(nC1, nR1);
  1365. pMat2->GetDimensions(nC2, nR2);
  1366. if (nC1 < nC2)
  1367. nMinC = nC1;
  1368. else
  1369. nMinC = nC2;
  1370. if (nR1 < nR2)
  1371. nMinR = nR1;
  1372. else
  1373. nMinR = nR2;
  1374. USHORT nMatInd;
  1375. ScMatrix* pResMat = GetNewMat(nMinC, nMinR, nMatInd);
  1376. if (pResMat)
  1377. {
  1378. for (i = 0; i < nMinC; i++)
  1379. {
  1380. for (j = 0; j < nMinR; j++)
  1381. {
  1382. if (pMat1->IsValueOrEmpty(i,j) && pMat2->IsValueOrEmpty(i,j))
  1383. pResMat->PutDouble(pMat1->GetDouble(i,j) /
  1384. pMat2->GetDouble(i,j), i, j);
  1385. else
  1386. pResMat->PutString(ScGlobal::GetRscString(
  1387. STR_NO_VALUE), i, j);
  1388. }
  1389. }
  1390. nRetMat = nMatInd;
  1391. }
  1392. return pResMat;
  1393. }
  1394. ScMatrix* ScInterpreter::MatPow(ScMatrix* pMat1, ScMatrix* pMat2)
  1395. {
  1396. USHORT nC1, nR1, nC2, nR2, nMinC, nMinR, i, j;
  1397. pMat1->GetDimensions(nC1, nR1);
  1398. pMat2->GetDimensions(nC2, nR2);
  1399. if (nC1 < nC2)
  1400. nMinC = nC1;
  1401. else
  1402. nMinC = nC2;
  1403. if (nR1 < nR2)
  1404. nMinR = nR1;
  1405. else
  1406. nMinR = nR2;
  1407. USHORT nMatInd;
  1408. ScMatrix* pResMat = GetNewMat(nMinC, nMinR, nMatInd);
  1409. if (pResMat)
  1410. {
  1411. for (i = 0; i < nMinC; i++)
  1412. {
  1413. for (j = 0; j < nMinR; j++)
  1414. {
  1415. if (pMat1->IsValueOrEmpty(i,j) && pMat2->IsValueOrEmpty(i,j))
  1416. pResMat->PutDouble(pow(pMat1->GetDouble(i,j),
  1417. pMat2->GetDouble(i,j)), i, j);
  1418. else
  1419. pResMat->PutString(ScGlobal::GetRscString(
  1420. STR_NO_VALUE), i, j);
  1421. }
  1422. }
  1423. nRetMat = nMatInd;
  1424. }
  1425. return pResMat;
  1426. }
  1427. ScMatrix* ScInterpreter::MatConcat(ScMatrix* pMat1, ScMatrix* pMat2)
  1428. {
  1429. USHORT nC1, nR1, nC2, nR2, nMinC, nMinR, i, j;
  1430. pMat1->GetDimensions(nC1, nR1);
  1431. pMat2->GetDimensions(nC2, nR2);
  1432. if (nC1 < nC2)
  1433. nMinC = nC1;
  1434. else
  1435. nMinC = nC2;
  1436. if (nR1 < nR2)
  1437. nMinR = nR1;
  1438. else
  1439. nMinR = nR2;
  1440. USHORT nMatInd;
  1441. ScMatrix* pResMat = GetNewMat(nMinC, nMinR, nMatInd);
  1442. if (pResMat)
  1443. {
  1444. for (i = 0; i < nMinC; i++)
  1445. {
  1446. for (j = 0; j < nMinR; j++)
  1447. {
  1448. if (pMat1->IsString(i,j) && pMat2->IsString(i,j))
  1449. {
  1450. String aTmp( pMat1->GetString(i,j) );
  1451. aTmp += pMat2->GetString(i,j);
  1452. pResMat->PutString( aTmp , i, j);
  1453. }

Large files files are truncated, but you can click here to view the full file