Maintain Cell Value If Condition is True - if-statement

What formula can I use to maintain a cell value (Integer) in excel if a certain condition is True?
*Example;
A6=5
A7=4
A8= A6 * A7 - which will give a value of 20 (in Cell A8) in this case*.
How can I maintain the 20 in cell A8 if the value of A6 was to be greater than 10 but allow is to change accordingly if it's less than 10?

Related

Cell value increasing by 1 when value in another cell reaches 100

In Google Sheets is it possible to have the value in cell A1 to increase by 1 when the value in B1 reaches 100 and also changing the value in B1 to -100?
So for example, "120" in B1 would change the value of A1 to "1" and change the value of B1 to "20".
Basically, I am looking to use the value of A1 as a whole number and the value in B1 as the decimal place but with a max of 99 on the decimal place.
Update following request for same but with varying max decimal numbers:
https://docs.google.com/spreadsheets/d/193Vbg9Dm4qDjIx4PNcmTOkMyPLdDaAr5-HaFkD1V2Eg/edit?usp=sharing
Columns A-C are input columns
Columns F-I are to work out the totals of the input columns for the relevant people and then to concatenate as a decimal figure
Columns K-N are updated totals using #player0's formula based on the max decimal place being 99 before it increases the whole number by 1 at 100.
So using the 44.120 total as an example, using decimal maximums of 50, 80 & 90 for when the whole number is changed:
For 50 - 44.120 would become 46.20
For 80 - 44.120 would become 45.40
For 90 - 44.120 would become 45.30
try:
=ARRAYFORMULA(SPLIT(REGEXREPLACE("0000"&A1:A6, "(.+)(.{2})$", "$1×$2"), "×"))
What want is not 100% able to be completed, but this is:
A
B
C
1
75
175
0
75
75
=IF(C1>100, LEFT(C1,1), "0")
=IF(C1>100, RIGHT(C1, 2), C1)
Input Number Here...

Counting Amount of subsets from a set

Let set S = {a1, a2, a3, ..., a12}, where all 12 elements are distinct. We wish to form subsets, each of which contains one or more of the elements of set S (including the possibility of using all the elements of S). The only restriction is that the subscript of each element in a specific set must be an integer multiple of the smallest subscript in that set. For example, {a2, a4, a6} is an acceptable set, as is {a6}. How many such sets can be formed?
I was thinking of dividing the problem in cases, one for 3 elements, and then 4 and 5 and so on. This would take way too long so can I have help doing it a faster way?
The constraint relates to the smallest subscript, so it makes more sense to branch on that, rather than branching on the size of the subset. You want to branch on something which simplifies the constraint, so instead of "each subscript is a multiple of the smallest subscript" you have e.g. "each subscript is a multiple of 3". Then within each branch it's much easier to count.
You only want to count non-empty subsets, so every subset has a smallest subscript:
If the subset contains a1, then each of the 11 remaining elements can be freely chosen as either present or not present. There are 211 such subsets.
If the smallest subscript is a2, then there are 5 possible other elements a4, a6, a8, a10, a12, each of which can be freely chosen as either present or not present. There are 25 such subsets.
If the smallest subscript is a3, then there are 3 possible other elements a6, a9, a12. There are 23 such subsets.
If the smallest subscript is a4, then there are 2 possible other elements a8, a12. There are 22 such subsets.
If the smallest subscript is a5 or a6, then there is one possible other element (a10 or a12 respectively). There are 2 subsets for a5 and 2 for a6.
Otherwise, the smallest subscript is a7, a8, a9, a10, a11, or a12, and the subset cannot contain any other elements due to the restriction. There is one subset in each case.
The total is therefore 211 + 25 + 23 + 22 + 2 + 2 + 1 + 1 + 1 + 1 + 1 + 1 = 2,102.
Generalising this argument, if there are n elements in the original set, then the total number of subsets satisfying this constraint is:

Data structure for fast range searches of dense dataset 4D vectors

I have millions of unstructured 3D vectors associated with arbitrary values - making for a set 4D of vectors. To make it simpler to understand: I have unixtime stamps associated with hundreds of thousands of 3D vectors. And I have many time stamps, making for a very large dataset; upwards of 30 millions vectors.
I have the need to search particular datasets of specific time stamps.
So lets say I have the following data:
For time stamp 1407633943:
(0, 24, 58, 1407633943)
(9, 2, 59, 1407633943)
...
For time stamp 1407729456:
(40, 1, 33, 1407729456)
(3, 5, 7, 1407729456)
...
etc etc
And I wish to make a very fast query along the lines of:
Query Example 1:
Give me vectors between:
X > 4 && X < 9 && Y > -29 && Y < 100 && Z > 0.58 && Z < 0.99
Give me list of those vectors, so I can find the timestamps.
Query Example 2:
Give me vectors between:
X > 4 && X < 9 && Y > -29 && Y < 100 && Z > 0.58 && Z < 0.99 && W (timestamp) = 1407729456
So far I've used SQLite for the task, but even after column indexing, the thing takes between 500ms - 7s per query. I'm looking for somewhere between 50ms-200ms per query solution.
What sort of structures or techniques can I use to speed the query up?
Thank you.
kd-trees can be helpful here. Range search in a kd-tree is a well-known problem. Time complexity of one query depends on the output size, of course(in the worst case all tree will be traversed if all vectors fit). But it can work pretty fast on average.
I would use octree. In each node I would store arrays of vectors in a hashtable using the timestamp as a key.
To further increase the performance you can use CUDA, OpenCL, OpenACC, OpenMP and implement the algorithms to be executed in parallel on the GPU or a multi-core CPU.
BKaun: please accept my attempt at giving you some insight into the problem at hand. I suppose you have thought of every one of my points, but maybe seeing them here will help.
Regardless of how ingest data is presented, consider that, using the C programming language, you can reduce the storage size of the data to minimize space and search time. You will be searching for, loading, and parsing single bits of a vector instead of, say, a SHORT INT which is 2 bytes for every entry - or a FLOAT which is much more. The object, as I understand it, is to search the given data for given values of X, Y, and Z and then find the timestamp associated with these 3 while optimizing the search. My solution does not go into the search, but merely the data that is used in a search.
To illustrate my hints simply, I'm considering that the data consists of 4 vectors:
X between -2 and 7,
Y between 0.17 and 3.08,
Z between 0 and 50,
timestamp (many of same size - 10 digits)
To optimize, consider how many various numbers each vector can have in it:
1. X can be only 10 numbers (include 0)
2. Y can be 3.08 minus 0.17 = 2.91 x 100 = 291 numbers
3. Z can be 51 numbers
4. timestamp can be many (but in this scenario,
you are not searching for a certain one)
Consider how each variable is stored as a binary:
1. Each entry in Vector X COULD be stored in 4 bits, using the first bit=1 for
the negative sign:
7="0111"
6="0110"
5="0101"
4="0100"
3="0011"
2="0010"
1="0001"
0="0000"
-1="1001"
-2="1010"
However, the original data that you are searching through may range
from -10 to 20!
Therefore, adding another 2 bits gives you a table like this:
-10="101010"
-9="101001" ...
...
-2="100010"
-1="100001" ...
...
8="001000"
9="001001" ...
...
19="001001"
20="010100"
And that's only 6 bits to store each X vector entry for integers from -10 to 20
For search purposes on a range of -10 to 20, there are 21 different X Vector entries
possible to search through.
Each entry in Vector Y COULD be stored in 9 bits (no extra sign bit is needed)
The 1's and 0's COULD be stored (accessed, really) in 2 parts
(tens place, and a 2 digit decimal).
Part 1 can be 0, 1, 2, or 3 (4 2-place bits from "00" to "11")
However, if the range of the entire Y dataset is 0 to 10,
part 1 can be 0, 1, ...9, 10 (which is 11 4-place bits
from "0000" to "1010"
Part 2 can be 00, 01,...98, 99 (100 7-place bits from "0000000" to "1100100"
Total storage bits for Vector Y entries is 11 + 7 = 18 bits in the
range 00.00 to 10.99
For search purposes on a range 00.00 to 10.99, there are 1089 different Y Vector
entries possible to search through (11x99) (?)
Each entry in Vector Z in the range of 0 to 50 COULD be stored in 6 bits
("000000" to "110010").
Again, the actual data range may be 7 bits long (for simplicity's sake)
0 to 64 ("0000000" to "1000000")
For search purposes on a range of 0 to 64, there are 65 different Z Vector entries
possible to search through.
Consider that you will be storing the data in this optimized format, in a single
succession of bits:
X=4 bits + 2 range bits = 6 bits
+ Y=4 bits part 1 and 7 bits part 2 = 11 bits
+ Z=7 bits
+ timestamp (10 numbers - each from 0 to 9 ("0000" to "1001") 4 bits each = 40 bits)
= TOTAL BITS: 6 + 11 + 7 + 40 = 64 stored bits for each 4D vector
THE SEARCH:
Input xx, yy, zz to search for in arrays X, Y and Z (which are stored in binary)
Change xx, yy, and zz to binary bit strings per optimized format above.
function(xx, yy, zz)
Search for X first, since it has 21 possible outcomes (range is -10 to 10)
- the lowest number of any array
First search for positive targets (there are 8 of them and better chance
of finding one)
These all start with "000"
7="000111"
6="000110"
5="000101"
4="000100"
3="000011"
2="000010"
1="000001"
0="000000"
So you can check if the first 3 bits = "000". If so, you have a number
between 0 and 7.
Found: search for Z
Else search for xx=-2 or -1: does X = -2="100010" or -1="100001" ?
(do second because there are only 2 of them)
Found: Search for Z
NotFound: next X
Search for Z after X is Found: (Z second, since it has 65 possible outcomes
- range is 0 to 64)
You are searching for 6 bits of a 7 bit binary number
("0000000" to "1000000") If bits 1,2,3,4,5,6 are all "0", analyze bit 0.
If it is "1" (it's 64), next Z
Else begin searching 6 bits ("000000" to "110010") with LSB first
Found: Search for Y
NotFound: Next X
Search for Y (Y last, since it has 1089 possible outcomes - range is 0.00 to 10.99)
Search for Part 1 (decimal place) bits (you are searching for
"0000", "0001" or "0011" only, so use yyPt1=YPt1)
Found: Search for Part 2 ("0000000" to "1100100") using yyPt2=YPt2
(direct comparison)
Found: Print out X, Y, Z, and timestamp
NotFound: Search criteria for X, Y, and Z not found in data.
Print X,Y,Z,"timestamp not found". Ask for new X, Y, Z. New search.

Checksum for binary PLC communication

I've been scratching my head around calculating a checksum to communicate with Unitronics PLCs using binary commands. They offer the source code but it's in a Windows-only C# implementation, which is of little help to me other than basic syntax.
Specification PDF (the checksum calculation is near the end)
C# driver source (checksum calculation in Utils.cs)
Intended Result
Below is the byte index, message description and the sample which does work.
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 24 25 26 27 28 29 | 30 31 32
# sx--------------- id FE 01 00 00 00 cn 00 specific--------- lengt CHKSM | numbr ot FF addr- | CHKSM ex
# 2F 5F 4F 50 4C 43 00 FE 01 00 00 00 4D 00 00 00 00 00 01 00 06 00 F1 FC | 01 00 01 FF 01 00 | FE FE 5C
The specification calls for calculating the accumuated value of the 22 byte message header and, seperately, the 6+ byte detail, getting the value of sum modulo 65536, and then returning two's complement of that value.
Attempt #1
My understanding is the tilde (~) operator in Python is directly derived from C/C++. After a day of writing the Python that creates the message I came up with this (stripped down version):
#!/usr/bin/env python
def Checksum( s ):
x = ( int( s, 16 ) ) % 0x10000
x = ( ~x ) + 1
return hex( x ).split( 'x' )[1].zfill( 4 )
Details = ''
Footer = ''
Header = ''
Message = ''
Details += '0x010001FF0100'
Header += '0x2F5F4F504C4300FE010000004D000000000001000600'
Header += Checksum( Header )
Footer += Checksum( Details )
Footer += '5C'
Message += Header.split( 'x' )[1].zfill( 4 )
Message += Details.split( 'x' )[1].zfill( 4 )
Message += Footer
print Message
Message: 2F5F4F504C4300FE010000004D000000000001000600600L010001FF010001005C
I see an L in there, which is a different result to yesterday, which wasn't any closer. If you want a quick formula result based on the rest of the message: Checksum(Header) should return F1FC and Checksum(Details) should return FEFE.
The value it returns is nowhere near the same as the specification's example. I believe the issue may be one or two things: the Checksum method isn't calculating the sum of the hex string correctly or the Python ~ operator is not equivalent to the C++ ~ operator.
Attempt #2
A friend has given me his C++ interpretation of what the calculation SHOULD be, I just can't get my head around this code, my C++ knowledge is minimal.
short PlcBinarySpec::CalcHeaderChecksum( std::vector<byte> _header ) {
short bytesum = 0;
for ( std::vector<byte>::iterator it = _header.begin(); it != _header.end(); ++it ) {
bytesum = bytesum + ( *it );
}
return ( ~( bytesum % 0x10000 ) ) + 1;
}
I'm not entirely sure what the correct code should be… but if the intention is for Checksum(Header) to return f705, and it's returning 08fb, here's the problem:
x = ( ~( x % 0x10000 ) ) + 1
The short version is that you want this:
x = (( ~( x % 0x10000 ) ) + 1) % 0x10000
The problem here isn't that ~ means something different. As the documentation says, ~x returns "the bits of x inverted", which is effectively the same thing it means in C (at least on 2s-complement platforms, which includes all Windows platforms).
You can run into a problem with the difference between C and Python types here (C integral types are fixed-size, and overflow; Python integral types are effectively infinite-sized, and grow as needed). But I don't think that's your problem here.
The problem is just a matter of how you convert the result to a string.
The result of calling Checksum(Header), up to the formatting, is -2299, or -0x08fb, in both versions.
In C, you can pretty much treat a signed integer as an unsigned integer of the same size (although you may have to ignore warnings to do so, in some cases). What exactly that does depends on your platform, but on a 2s-complement platform, signed short -0x08fb is the bit-for-bit equivalent of unsigned 0xf705. So, for example, if you do sprintf(buf, "%04hx", -0x08fb), it works just fine—and it gives you (on most platforms, including everything Windows) the unsigned equivalent, f705.
But in Python, there are no unsigned integers. The int -0x08fb has nothing to do with 0xf705. If you do "%04hx" % -0x08fb, you'll get -8fb, and there's no way to forcibly "cast it to unsigned" or anything like that.
Your code actually does hex(-0x08fb), which gives you -0x8fb, which you then split on the x, giving you 8fb, which you zfill to 08fb, which makes the problem a bit harder to notice (because that looks like a perfectly valid pair of hex bytes, instead of a minus sign and three hex digits), but it's the same problem.
Anyway, you have to explicitly decide what you mean by "unsigned equivalent", and write the code to do that. Since you're trying to match what C does on a 2s-complement platform, you can write that explicit conversion as % 0x10000. If you do "%04hx" % (-0x08fb % 0x10000), you'll get f705, just as you did in C. And likewise for your existing code.
It's quite simple. I checked your friend's algorithm by adding all the header bytes manually on a calculator, and it yields the correct result (0xfcf1).
Now, I don't actually know python, but it looks to me like you are adding up half-byte values. You have made your header string like this:
Header = '2F5F4F504C4300FE010000004D000000000001000600'
And then you go through converting each byte in that string from hex and adding it. That means you are dealing with values from 0 to 15. You need to consider every two bytes as a pair and convert that (values from 0 to 255). Or you need to use actual binary data instead of a text representation of the binary data.
At the end of the algorithm, you don't really need to do the ~ operator if you don't trust it. Instead you can do (0xffff - (x % 0x10000)) + 1. Bear in mind that prior to adding 1, the value might actually be 0xffff, so you need to modulo the entire result by 0x10000 afterwards. Your friend's C++ version uses the short datatype so no modulo is necessary at all because the short will naturally overflow

Hamming code given a generator matrix question

Can I just say from the outset that this isn't a homework question as I'm way to
old for that. But is related to an open source radio decoder project I'm working on ..
http://github.com/IanWraith/DMRDecode
Part of the radio protocol I'm interested uses a Hamming (7,4,3) code to protect
4 bits in a particular part of a data packet. So for every 4 bits of data it adds
3 parity bits which is easy enough for me even 20 years after I studied this at
technical college. The specification document just gives the Hamming generator matrix which is as follows
1000 101
0100 111
0010 110
0001 011
DDDD HHH
1234 210
Now my question is does this mean the following ..
H2 is the XORed product of D1 , D2 , D3
H1 is the XORed product of D2 , D3 , D4
H0 is the XORed product of D1 , D2 , D4
or have I got this horribly wrong ?
Thanks for your time.
Ian
For the generator matrix you give, your interpretation is correct. Your tables do mean:
H0 = D1 ^ D2 ^ D4
H1 = D2 ^ D3 ^ D4
H2 = D1 ^ D2 ^ D3
However, the normal Hamming(7,4) matrix, in the same notation would be
1000 011
0100 101
0010 110
0001 111
DDDD HHH
1234 210
Only H0 is the same among the two sets of matrices. The other two bits are
H1 = D1 ^ D3 ^ D4
H2 = D2 ^ D3 ^ D4
It would be handy to be sure that the specification actually matches what's done in practice.
Equally critical is the specification for the order of the bits in the transmitted word. For instance, for the typical Hamming(7,4) encoding, the order
H0, H1, D1, H2, D2, D3, D4
has the property that the XOR with the parity check matrix tells you either (1) that all bits seem to be correct (== {0,0,0}) or (2) one bit appears to be wrong and it is the one in the bit position given by the result of the parity check matrix. I.e., if the three bits returned from multiplying the received code by the parity check matrix are {1, 0, 1}, then the 5th bit (101 interpreted in base 2) has been flipped. In the above ordering, this means D2 has been flipped.
This article, Hamming(7,4), will tell you more than you want to know about how to construct the parity bits and where they are encoded into the output.