linsolve bug
|
08-24-2023, 01:57 PM
Post: #1
|
|||
|
|||
linsolve bug
Tested on HP-Prime emulator 2.1.14181 (2018 10 16), and XCas 1.9.0-31 (mingw win32)
Example taken from Accuracy of Quadratic Regression, solving quadratic regression coefficients. Matrix A reduced to a diagonal matrix. We can read off the answer, coefficients = b/a Cas> a := [1.53963596424e50, 9.47961058243e35, 7.07482042846e19]; /* diagonals */ Cas> b := [-8.42134216805e50,2.08648957898e40,-1.56645830033e27]; /* last column */ Cas> linsolve(diag(a), b) → [] // ??? Cas> linsolve(diag(a*1), b*1) // why *1 make a difference? [−5.4696969697, 22010.2878788, −22141315.3333] Cas> a := a*1 Cas> b := b*1 Cas> linsolve(diag(a), b) → [] // *1 not work now ... |
|||
08-24-2023, 02:24 PM
Post: #2
|
|||
|
|||
RE: linsolve bug
This comes from the default value of epsilon: 9e35 is considered to be 0 when compared to 1.5e50 and the matrix is viewed like a singular matrix (2nd row==0).
If you change epsilon to a smaller value (e.g. 1e-30), you will get what you expect. |
|||
08-24-2023, 04:12 PM
Post: #3
|
|||
|
|||
RE: linsolve bug
Thanks for the tip! For my example, smaller epsilon help XCas, but not HP Prime Cas
XCas> epsilon := 1e-30 XCas> linsolve(diag(a), b) [-5.4696969697, 22010.2878788, -22141315.3333] Cas> epsilon := 1e-30 Cas> linsolve(diag(a), b) [C_0, C_1, C_2] This symbolic result appears if epsilon is 1e-16 or smaller. |
|||
08-25-2023, 03:19 PM
Post: #4
|
|||
|
|||
RE: linsolve bug
The public firmware version of giac is probably too old. It works with an up to date giac version (I checked on the emulator).
|
|||
08-25-2023, 04:34 PM
Post: #5
|
|||
|
|||
RE: linsolve bug
Some of linsolve accuracy issue may be my upgrade from XCas 1.5.0 to 1.9.0
Float precision is reduced, from 53-bits mantissa IEEE double, to 48 (what HP Prime Cas has) Worse, XCas 1.9.0 now round the same as HP Prime Cas too ... truncation! Cas> h := 2^48 - 1.0 Cas> 2.96+h-h → 1.03125 // same as XCas 1.9.0 Cas> 2.97+h-h → 3.03125 // same as XCas 1.9.0 With ill-conditioned matrix, lost of precision and losing round-to-nearest matters! Code: /* sx[k] = sum(X.^k), syx[k] = sum(Y.*X.^k) */ XCas 1.5.0 --> [-5.46969697020, 22010.2878808] XCas 1.9.0 --> [-5.46452227167, 21989.5114662] |
|||
08-25-2023, 06:58 PM
Post: #6
|
|||
|
|||
RE: linsolve bug
Giac is using 48 bits mantissa by default, unless it is compiled with the -DDOUBLEVAL flag. At least on linux. On windows, I don't remember, perhaps it is different for the 32 bits cygwin version, 64 bits cygwin version and 64 bits mingw version ("native").
This is done in order to have 5 bits to store the type of a gen (generic C type to represent an object) and keep sizeof(gen)=8 bytes=64 bits. If -DDOUBLEVAL is used, then sizeof(gen)=12 bytes on 32 bits architectures and =16 bytes on 64 bits architectures. This means that objects are larger, e.g. matrices take twice more space, which slow down computations (especially when the L1 cache limit is reached). 48 bits is sufficient except for bad conditionned computations, and if you need more then you can calculate with longfloats using e.g. evalf(.,30) to have 30 digits. Multiprecision floats are currently not available on the Prime, they could be sometimes in the future, with quickjs, already available on other calculator ports of giac. |
|||
08-25-2023, 08:24 PM
(This post was last modified: 08-27-2023 12:40 AM by Albert Chan.)
Post: #7
|
|||
|
|||
RE: linsolve bug
(10-04-2018 07:22 PM)parisse Wrote: Xcas is using longfloats (via MPFR) for representation of floats having more than 14 digits. I totally forget about XCas longfloats ! Digits := 16 (or via Setup), and rerun code unchanged, it matched IEEE double accuracy. BTW, last number is in normalized float notation. XCas-1.9.0 --> [-5.469696970203201, 0.2201028788082040e5] Update: MPFR bits = ceil(digits / log10(2)) --> 16 digits == 54 bits. |
|||
08-26-2023, 02:57 PM
Post: #8
|
|||
|
|||
RE: linsolve bug
FYI, this is result of time(linsolve(a,b)). Timing 2nd digit is just a rough guess.
Code: XCas-1.5.0: TIME MPFR timings are basically the same, regardless of setting digits to 16 or 32, or even 100. Order of magnitude difference between 48 bits and IEEE double is odd. Perhaps comparing wildly different XCas versions is not a good idea. But, that's the only 2 versions I had to test. Anyone has XCas 1.90 (win32), compiled with the -DDOUBLEVAL flag ? |
|||
08-27-2023, 06:47 AM
Post: #9
|
|||
|
|||
RE: linsolve bug
Your systems are too small to be able to deduce something meaningfull. You should try with a randmatrix of order a few hundreds to be able to see something.
|
|||
08-27-2023, 09:15 AM
Post: #10
|
|||
|
|||
RE: linsolve bug
100×100 matrix, speed ratio dropped to 2X, which may be due to XCas versions alone
randseed(0); m := float(ranm(100,100)); time(inverse(m)) Note: both XCas versions produce same random matrix, and can be inverted. Code: XCas-1.5.0 TIME |
|||
08-28-2023, 01:03 PM
Post: #11
|
|||
|
|||
RE: linsolve bug
(08-24-2023 02:24 PM)parisse Wrote: This comes from the default value of epsilon: 9e35 is considered to be 0 when compared to 1.5e50 It may be better *not* to flush numbers to zero. It may make things worse. Perhaps a warning of possibly rounding issues enough? (08-25-2023 12:06 AM)Albert Chan Wrote: \(\left[\begin{array}{cccc}162415528660693&80903876075&40300645&44588891682\\80903876075&40300645&20075&22207030\\40300645&20075&10&11060\end{array}\right]\) Matrix Column Operations Wrote:We could apply same column operations on top. Continued on from above: I was writing this post on column operations, but the answer was wrong! Column operations does not change values of true a = -361/66 = -5.4(69) Reduced m, with nice small numbers, seems innocently enough. Without warning, rref(m) flushed some numbers to zero, and give wrong result. Making epsilon smaller help ... but it is hard to know ahead of time. Cas> epsilon := 1e-30 /* was 1e-12 */ Cas> rref(m) \(\left(\begin{array}{cccc} 1.0 & 0.0 & 0.0 & -5.46969697435 \\ 0.0 & 1.0 & 0.0 & 11032.6060699 \\ 0.0 & 0.0 & 1.0 & 1125.03030307 \end{array}\right) \) We undo column operations, to get original variables (a, b, c) Cas> r := col(Ans, 0) Cas> r(3) -= 2007 * r(2) Cas> r(2) -= 2007 * r(1) [−5.46969697435, 22010.2878975, −22141315.3521] |
|||
« Next Oldest | Next Newest »
|
User(s) browsing this thread: 2 Guest(s)