Login [Register]
Don't have an account? Register now to chat, post, use our tools, and much more.
This is an archived, read-only copy of the United-TI subforum , including posts and topic from May 2003 to April 2012. If you would like to discuss any of the topics in this forum, you can visit Cemetech's TI-BASIC subforum. Some of these topics may also be directly-linked to active Cemetech topics. If you are a Cemetech member with a linked United-TI account, you can link United-TI topics here with your current Cemetech topics.

This forum is locked: you cannot post, reply to, or edit topics. TI-Basic => TI-BASIC
Author Message
Ed H


Member


Joined: 30 Nov 2007
Posts: 138

Posted: 11 Nov 2009 07:31:54 pm    Post subject:

Those who have been frequented this forum for a while have probably seen my program for finding the molecular mass of a chemical compound. One annoyance I had about the old programs was that it required a ~1000 byte list to store the atomic mass of every element, and that list had to be transferred separately from the program. This is an improved version that contains the list compressed in the beginning of the program.

In my opinion, this program is already very well optimized, taking up a total of 1282 bytes, but I'm fairly sure I can compress the list smaller. The list takes up about 600 bytes in the program. I'm looking for a way to do it better.

Anyway, check it out. Here's some screens of the program:
[attachment=2903:screen1.gif]

[attachment=2904:screen2.gif]

[attachment=2906:screen3.gif]
(lol)

[attachment=2902:MOLCMASS.8xp]
Back to top
ztrumpet


Active Member


Joined: 06 May 2009
Posts: 555

Posted: 11 Nov 2009 07:41:26 pm    Post subject:

That looks really good. Will that help me later this year in Chemistry?
Back to top
calcdude84se


Member


Joined: 09 Aug 2009
Posts: 207

Posted: 11 Nov 2009 08:21:16 pm    Post subject:

Given that there is no true pattern to the numbers, it wouldn't be easy to compress it. I can't think of a lot of compression techniques, and most are assembly. I take it you want to keep your program pure BASIC. You might be able to compress in pure BASIC, but it would be slow and the total program size would probably be larger than what it is now.

As a side note, awesome program! :biggrin:
Back to top
Ed H


Member


Joined: 30 Nov 2007
Posts: 138

Posted: 11 Nov 2009 09:36:27 pm    Post subject:

ztrumpet wrote:
That looks really good. Will that help me later this year in Chemistry?

For sure! Finding molecular masses is something you'll do a lot in a basic chemistry class, and it's something that I found really tedious. It's really just looking up the masses on the periodic table and doing some arithmetic, but it does reduce a lot of the tedium from the classwork.

calcdude84se wrote:
Given that there is no true pattern to the numbers, it wouldn't be easy to compress it. I can't think of a lot of compression techniques, and most are assembly. I take it you want to keep your program pure BASIC. You might be able to compress in pure BASIC, but it would be slow and the total program size would probably be larger than what it is now.

As a side note, awesome program! Very Happy

Thanks!
I do intend to keep this version in pure BASIC. You're right that I probably wouldn't be able to use any actual compression techniques. Right now I am basically using TI-Basic tricks. For example, one way to compress the original list, written out in a BASIC program, is to write cumSum({1.00794,2.99466,2.9384.... This reduces the size of the list by ~100 bytes, simply because the numbers have fewer digits! Currently, what I'm doing is approximating the atomic mass with a quadratic equation (.003X²+2.3X-8), and then storing the difference in a list, which saves ~140 bytes, again, because the numbers in the list have fewer digits.

On a side note, I have always wanted to write this program in ASM, but I never got around to learning ASM like I planned to. If anyone would like to write an ASM program for finding the molecular mass, I'd be glad to explain my algorithm, or contribute in any way.

Thanks all! Very Happy


Last edited by Guest on 01 Jul 2010 10:21:02 am; edited 1 time in total
Back to top
thornahawk
μολών λαβέ


Active Member


Joined: 27 Mar 2005
Posts: 569

Posted: 12 Nov 2009 01:28:13 am    Post subject:

Ed H wrote:
Currently, what I'm doing is approximating the atomic mass with a quadratic equation (.003X²+2.3X-8), and then storing the difference in a list, which saves ~140 bytes, again, because the numbers in the list have fewer digits.


I'm feeling slow today... would you mind expanding on how exactly does that quadratic help in your data compression?

I'm assuming you've checked and made sure that all the atomic masses are returned to their proper number of significant figures (i.e. the compression method you used did not affect the accuracy of the atomic masses returned). ;)

thornahawk


Last edited by Guest on 01 Jul 2010 10:21:20 am; edited 1 time in total
Back to top
ah-blabla


Newbie


Joined: 28 Oct 2009
Posts: 26

Posted: 12 Nov 2009 03:39:51 am    Post subject:

calcdude84se wrote:
Given that there is no true pattern to the numbers, it wouldn't be easy to compress it. I can't think of a lot of compression techniques, and most are assembly. I take it you want to keep your program pure BASIC. You might be able to compress in pure BASIC, but it would be slow and the total program size would probably be larger than what it is now.

As a side note, awesome program! :biggrin:

[s]There is a pattern: they are always increasing at least, so you could store the difference to the preceding number; or: to calculate the mass of an atom, we know there are X protons - this doesn't change, where X is atomic number, if you have the elements ordered in a list, this is stored by the elements position in the list, meaning you only have to store one additional, smaller, number, the average number of neutrons in a nucleus, i.e. average mass - number of protons. I doubt this would save any/much space (this depends on how the numbers are stored, but in Basic they are stored as text aren't they? In this case these method might save a little space. The second method definitely has a lot less overhead than the first).[/s]

Sorry, that's what Ed H just suggested, in a more simplified form (i.e. without "compression" isn't it?). You could try changing the base of numbers stored from base 2 to base ~200 though (i.e. using all possible characters in the calc), which would save some space, but first a conversion algorithm needs to be made, and it wouldn't be particularly efficient for numbers on the scale we are using.


Last edited by Guest on 12 Nov 2009 06:35:11 am; edited 1 time in total
Back to top
Ed H


Member


Joined: 30 Nov 2007
Posts: 138

Posted: 12 Nov 2009 09:35:01 pm    Post subject:

thornahawk wrote:
Ed H wrote:
Currently, what I'm doing is approximating the atomic mass with a quadratic equation (.003X²+2.3X-8), and then storing the difference in a list, which saves ~140 bytes, again, because the numbers in the list have fewer digits.


I'm feeling slow today... would you mind expanding on how exactly does that quadratic help in your data compression?

I'm assuming you've checked and made sure that all the atomic masses are returned to their proper number of significant figures (i.e. the compression method you used did not affect the accuracy of the atomic masses returned). ;)

thornahawk

Heh, what I'm doing isn't really compression. I write my list out in the beginning of the program, and since it's being stored in the program (as a string) rather in list format, the number of digits each number takes up matters. The "compression" methods I'm using simply reduce the number of digits each number takes up. By approximating the numbers and storing only the differences, I save 140 bytes by taking off 1-2 digits from most of the numbers.

Edit: Whoops, I'm actually using int(.003X²+2.3X-8 to approximate the atomic number. Thus, there won't be any problems with significant figures, when I add the stored difference to the approximation.


Last edited by Guest on 01 Jul 2010 10:21:40 am; edited 1 time in total
Back to top
TI-newb


Member


Joined: 24 Dec 2008
Posts: 158

Posted: 18 Nov 2009 10:22:45 pm    Post subject:

Hmm. this looks awsome: And just for an idea? (this will definetly affect speed) You can always just put the number of Neutrons on the List.. and have a For( to get the numbers out.. (<- Sorry, doesnt explain much does it.. il explain in more detail)

If im correct, its Protons + Neutrons = Atomic Mass? So if u stored only the Neutrons to the List, you know the Protons go UP by one every single.. element.. So what u do to get it out is have the element #(supplied by the user?) + the Neutrons. (This will only save bytes when u reach the low 3 digit numbers..)

So yeah, just pointing out ideas, and since i dont know how your getting the inputs of names, and recognizing them. i cant really give u any solid ideas.


In my brain, i was thinking of doing

Repeat (the number of protons) = (the number the guy picked) (then i realized you might as well just put.. (the number the guy picked) -> X or something)

so yeah, idk if speed will be affected. and you can still do the earlier optimizations you stated.


Last edited by Guest on 18 Nov 2009 10:24:52 pm; edited 1 time in total
Back to top
ztrumpet


Active Member


Joined: 06 May 2009
Posts: 555

Posted: 19 Nov 2009 12:04:54 pm    Post subject:

[quote name='TI-newb' post='138750' date='Nov 18 2009, 10:22 PM']If im correct, its Protons + Neutrons = Atomic Mass? So if u stored only the Neutrons to the List, you know the Protons go UP by one every single.. element.. So what u do to get it out is have the element #(supplied by the user?) + the Neutrons. (This will only save bytes when u reach the low 3 digit numbers..)[/quote]
You are correct and that's a great idea! That's a very good way to store the masses.
Back to top
Ed H


Member


Joined: 30 Nov 2007
Posts: 138

Posted: 19 Nov 2009 11:21:25 pm    Post subject:

TI-newb wrote:
Hmm. this looks awsome: And just for an idea? (this will definetly affect speed) You can always just put the number of Neutrons on the List.. and have a For( to get the numbers out.. (<- Sorry, doesnt explain much does it.. il explain in more detail)

If im correct, its Protons + Neutrons = Atomic Mass? So if u stored only the Neutrons to the List, you know the Protons go UP by one every single.. element.. So what u do to get it out is have the element #(supplied by the user?) + the Neutrons. (This will only save bytes when u reach the low 3 digit numbers..)

So yeah, just pointing out ideas, and since i dont know how your getting the inputs of names, and recognizing them. i cant really give u any solid ideas.


In my brain, i was thinking of doing

Repeat (the number of protons) = (the number the guy picked) (then i realized you might as well just put.. (the number the guy picked) -> X or something)

so yeah, idk if speed will be affected. and you can still do the earlier optimizations you stated.


I get the atomic number using int(.5inString(" H HeLiBeB C N O ...", which requires me to write down a big 223-letter string. =)

Thank you for the idea! I'm already doing something similar to what you're suggesting: "approximating" the atomic mass using an integer equation, and then storing the difference between the approximate and actual values in a list.

I'd like to point out a subtlety here: atomic masses usually aren't integer numbers, and the reason for this is atomic masses are actually the average masses of all the isotopes of an element weighted by their commonness. For example, naturally occurring carbon usually has 6 neutrons, but about 1% of carbon actually has 7 neutrons. Thus, the atomic mass is actually 12.0107. This is makes the atomic masses take up so much memory, even though many of them are close to integer values.


Last edited by Guest on 01 Jul 2010 10:22:11 am; edited 1 time in total
Back to top
TI-newb


Member


Joined: 24 Dec 2008
Posts: 158

Posted: 19 Nov 2009 11:37:27 pm    Post subject:

I guess =D, but u can still just make a slightly smaller list by doing..
:1->X
:Repeat X=Dim(L1
:L1(X)-X->L2(X
:X+1->X
:End

If im not wrong, this will get the Neutrons into list2, and u can make list2 into list1 again, or whatever. (and i trust u know the Rcl button)(if you dont know what the Rcl button is, just press Rcl, and then put L2.. or L1, and it will insert it into the prgm u are currently in.)

EDIT: Some people dont have the Lower Case lettering, and in some cases, dont know where to get them (ME!), can u tell us.. or attach a file that allows lower cases? =D thanks. and i find ur string recognition cool, ive only really played around with lists.


Last edited by Guest on 19 Nov 2009 11:38:47 pm; edited 1 time in total
Back to top
Eeems


Advanced Member


Joined: 25 Jan 2009
Posts: 277

Posted: 20 Nov 2009 12:50:15 am    Post subject:

To get lowercase, just use either DCS, Mirage, or Celtic III to turn it on. Also if you search it up on ticalc, there are many different programs that will turn it on/give you a string filled with them.
Back to top
thornahawk
μολών λαβέ


Active Member


Joined: 27 Mar 2005
Posts: 569

Posted: 20 Nov 2009 11:01:53 am    Post subject:

So you're suggesting he store info on isotopes (which can be as few as three and as many as thirty-six) and their natural abundances, and then just calculate the atomic mass? That sounds more complicated y'know... :)

Again, unless you take number of isotopes and abundances in account, you don't arrive at the currently accepted atomic weights just by adding up proton an neutron weights, sorry.

thornahawk
Back to top
DrDnar


Member


Joined: 28 Aug 2009
Posts: 116

Posted: 20 Nov 2009 03:00:26 pm    Post subject:

Actually, approximating a data set with a function and then storing the difference is a real compression technique used in FLAC. A compression ratio of 1.7 is already pretty good, and about average for FLAC-encoded media. It looks like deflate (used in ZIPs) could reduce that to 450 bytes (350 if you compress your compressed data). Note that deflate would require an assembly program to properly decompress. While you could do it in BASIC (using base-10), you wouldn't be able to get the bit-level compression, and there'd be a lot of overhead. For a BASIC program, your solution is pretty smart. Perhaps you can improve the polynomial to improve compression.

That's also probably the best compression technique for an assembly program. If you used deflate to compress the data, you'd need to write a semi-complicated decoder, which would take up space, and is slow. For your technique, the assembly program could store the actual numeric data in BCD, halving the size. However, the decompression would still need to invoke the TIOS floating point routines (unless you used some crazy integer math) to decompress, so it wouldn't even be much faster.


Last edited by Guest on 20 Nov 2009 03:39:42 pm; edited 1 time in total
Back to top
Ed H


Member


Joined: 30 Nov 2007
Posts: 138

Posted: 22 Nov 2009 08:41:03 pm    Post subject:

Dr. D wrote:
Actually, approximating a data set with a function and then storing the difference is a real compression technique used in FLAC. A compression ratio of 1.7 is already pretty good, and about average for FLAC-encoded media. It looks like deflate (used in ZIPs) could reduce that to 450 bytes (350 if you compress your compressed data). Note that deflate would require an assembly program to properly decompress. While you could do it in BASIC (using base-10), you wouldn't be able to get the bit-level compression, and there'd be a lot of overhead. For a BASIC program, your solution is pretty smart. Perhaps you can improve the polynomial to improve compression.

That's also probably the best compression technique for an assembly program. If you used deflate to compress the data, you'd need to write a semi-complicated decoder, which would take up space, and is slow. For your technique, the assembly program could store the actual numeric data in BCD, halving the size. However, the decompression would still need to invoke the TIOS floating point routines (unless you used some crazy integer math) to decompress, so it wouldn't even be much faster.


Ah, you make me want to take up ASM coding so I can try all this stuff! :D

Now, for ASM, I think storing the numbers as integers is not a bad idea! One possibility is to store the masses as 4-byte integers, equal to 10^5 times the masses. (I believe this is also called fixed-point?) This would give me the same 5 digits of precision after the decimal point that I currently enjoy in the BASIC program, and I think would be fairly easy to perform math on - the only operations used here are addition, and multiplying by an integer. Storing the 111 numbers this way takes up 444 bytes. If I used my current "approximation-difference" technique for compression, I would probably approximate the atomic mass of the Nth element linearly (something like 262144 * N), and then store the differences as signed 3-byte integers, bringing the size of the array down to 333 bytes.

Okay, so it SOUNDS like a pretty good idea to me, but I've never actually coded an ASM program before. Does this seem like it would work?


Last edited by Guest on 01 Jul 2010 10:20:08 am; edited 1 time in total
Back to top
DrDnar


Member


Joined: 28 Aug 2009
Posts: 116

Posted: 24 Nov 2009 12:03:44 am    Post subject:

I personally wouldn't bother. BASIC provides excellent access to the TIOS's math function. It might be a little slow in this case, but it's not a real issue. Text input has its troubles in assembly. The biggest advantage would be that you could extract each compressed datum on-the-fly (scanning the table is fast), instead of caching the decompressed data, like you do. For the sort of small molecules students work with in basic chemistry, this would indeed be faster.

Fixed-point could be possible, but you'd have to write some math routines for yourself. I don't think 3-byte offsets will work; there isn't enough resolution. You'll also have to write a 24- by 8-bit multiply. As an upshot, you wouldn't have to scan the array to find the data. It could work. If you really wanted to use this as an introduction to assembly, go for it. Also, it's mantissa, not mass.


Graph your data. Anything stand out? Especially around, say, element 60?
Back to top
thornahawk
μολών λαβέ


Active Member


Joined: 27 Mar 2005
Posts: 569

Posted: 27 Nov 2009 11:33:09 am    Post subject:

D'nar,

Ed did mean "masses" in his post, it looks. To the number of significant figures retained, multiplying all those atomic masses by 105 would give integers.

Anyway, here's a nice atomic mass versus atomic number plot:



thornahawk
Back to top
Ed H


Member


Joined: 30 Nov 2007
Posts: 138

Posted: 27 Nov 2009 06:54:48 pm    Post subject:

[quote name='Dr. D'nar' post='138940' date='Nov 23 2009, 11:03 PM']I personally wouldn't bother. BASIC provides excellent access to the TIOS's math function. It might be a little slow in this case, but it's not a real issue. Text input has its troubles in assembly. The biggest advantage would be that you could extract each compressed datum on-the-fly (scanning the table is fast), instead of caching the decompressed data, like you do. For the sort of small molecules students work with in basic chemistry, this would indeed be faster.

Fixed-point could be possible, but you'd have to write some math routines for yourself. I don't think 3-byte offsets will work; there isn't enough resolution. You'll also have to write a 24- by 8-bit multiply. As an upshot, you wouldn't have to scan the array to find the data. It could work. If you really wanted to use this as an introduction to assembly, go for it. Also, it's mantissa, not mass.


Graph your data. Anything stand out? Especially around, say, element 60?[/quote]

What I imagined was compressing the data in 3-byte integers, but doing the calculations on 4-byte integers. The atomic masses follow a very strong linear trend, and 3-byte offsets are sufficient to store all the masses.

What I'm most worried about is interpreting the input string (which I would probably just pull from Ans, being reluctant to write an input routine). This seems like it would be difficult.

Anyway, thank you for that catch on element 60 - I had the mass stored as 114.242, when it should be 144.242. I'm not sure how I didn't notice this earlier.

Hmm, it seems to me I should probably open up a topic in the ASM forum, as the course of this topic has shifted from the original BASIC program.
Back to top
Display posts from previous:   
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
    »
» View previous topic :: View next topic  
Page 1 of 1 » All times are GMT - 5 Hours

 

Advertisement