I get very confused at times with the shorthand increment operation.
Since when i was little programming in BASIC, i got some how stuck with a = a+1 which is long painful way of saying 'Get a's current value, add 1 to it and then store the new value back to a'.
1] a = a +1 ;
2] a++ ;
3] ++a;
4] a +=1;
[1] and [4] are similar in functionality different in notation, right?
2] and 3] work simply differently because of the fact that the increment signs ++ is before and after. Right?
Am I safe to assume the below?
int f(int x){ return x * x;}
y = f(x++) -> for x =2, f(x) = x^2
f(x) ======> y= 2^2 =4
x=x+1; ======> x= 2+1 = 3
y = f(++x) -> for x =2, f(x) = x^2
x=x+1 ===========> x = 2+1 = 3
f(x) ===========> y =3^2 = 9
Difference is, what the operator returns:
The post-increment operator "a plus plus" adds one, and returns the old value:
int a = 1;
int b = a++;
// now a is 2, b is 1
The pre-increment operator "plus plus a" adds one, and returns the new value:
a = 1;
b = ++a;
// now a is 2 and b is 2
First off, you should read this answer very carefully:
What is the difference between i++ and ++i?
And read this blog post very carefully:
http://blogs.msdn.com/b/ericlippert/archive/2011/03/29/compound-assignment-part-one.aspx
Note that part two of that post was an April Fool's joke, so don't believe anything it says. Part one is serious.
Those should answer your questions.
When you have just an ordinary local variable, the statements x++; ++x; x = x + 1; x += 1; are all basically the same thing. But as soon as you stray from ordinary local variables, things get more complicated. Those operations have subtleties to them.
1], 3] and 4] are functionally identical - a is incremented by one, and the value of the whole expression is the new value of a.
2] is different from the others. It also increments a, but the value of the expression is the previous value of a.
Related
I'm dealing with the following assignment, and as I'm not very familiar with recursion I'm at a loss. I'd greatly appreciate it if someone with more experience could point me in the right direction.
The assignment reads as follows:
Write a console application that determines all combinations of '+' and '-' operators which can be put between natural numbers ranging from 1 to a given N >=2, so that the result of the expression is a given X number. If there is no possible combination, the application will output 'N/A'.
Ex:
For inputs:
6 //N
3 //X
The console will read:
1 + 2 + 3 - 4 - 5 + 6 = 3
1 + 2 - 3 + 4 + 5 - 6 = 3
1 - 2 - 3 - 4 + 5 + 6 = 3
Given the circumstances of the assignment, I'm not allowed to use any other directive than 'System'. I've found several versions of this 'Coin Change' problem, but mostly in C++ or Python and also quite different than my current assignment. I'm not asking anyone to do my assignment for me, I'm simply looking for some valid pointers so I know where to start.
This code sample should help you. You can adapt this recursion to your needs, since it only counts number of such combinations.
Take into account that this approach is quite slow, you can find some DP solutions that are much faster.
private static int Search(int start, int end, int cur, int searched)
{
if (start > end)
{
return Convert.ToInt32(cur == searched);
}
return Search(start + 1, end, cur + start, searched) + Search(start + 1, end, cur - start, searched);
}
static void Main(string[] args)
{
int result = Search(2, 6, 1, 3);
}
I would make a function (let's call it f) that takes 5 parameters: The current number, the end number (N), the desidered result (X), the formula so far and the result of the formula so far.
In the function you first test if the current number is the end number. If it is, then test if the result of the formula is the desired number. If it is, print the formula.
If you're not at the end yet, then call the function itself twice. Once where you add the next number and once where you subtract it.
The first call to the function would be
f(1, 6, 3, "1", 1). It would then call itself twice with
f(2, 6, 3, "1 + 2", 3) and
f(2, 6, 3, "1 - 2", -1)
Then it would continue like that until it reaches the calls with 6 numbers in the formula where it would check if the result is 3.
Hope that helps you get started.
This answer strives to be the pinnacle in the art of helping without helping.
Which is what was asked for.
So here, the complete albeit a bit obfuscated solution in a language, you might have never heard of. But if you think about what you see long enough, you might get an idea how to solve this in C#.
data Expr = Lit Integer | Add | Sub deriving(Show)
compute :: [Expr] -> Integer -> Integer
compute [] value = value
compute (Add : Lit x : rest) value = compute rest (value + x)
compute (Sub : Lit x : rest) value = compute rest (value - x)
compute (Lit x1 : Add : Lit x2 : rest) value = compute rest (value + x1 + x2)
compute (Lit x1 : Sub : Lit x2 : rest) value = compute rest (value + x1 - x2)
compute [Lit x] _ = x
solve :: Integer -> [Integer] -> [Expr] -> [[Expr]] -> [[Expr]]
solve goal [] current found
| goal == compute current 0 = current : found
| otherwise = found
solve goal (n:ns) current found =
solve goal ns (current ++ [Add, Lit n]) []
++ solve goal ns (current ++ [Sub, Lit n]) []
prettyFormula :: [Expr] -> String
prettyFormula f =
concat $ fmap (\xp -> case xp of
Lit n -> show n
Add -> "+"
Sub -> "-") f
With that loaded and with fmap prettyFormula (solve 3 [2..6] [Lit 1] []) in the REPL, you get your result:
["1+2+3-4-5+6","1+2-3+4+5-6","1-2-3-4+5+6"]
This question already has answers here:
Behaviour and Order of evaluation in C# [duplicate]
(2 answers)
Closed 2 years ago.
As a beginner, I had difficulty understanding the code below.
I expected the a increments twice and the result will be 2 but it isn't.
var a = 0;
a += ++a;
Console.WriteLine(a); // 1
It seems like one value is dropped. How to understand that?
Well, a += n is equivalent to a = a + n
a += ++a; is therefore equivalent to a = a + ++a;
In turn, this is equivalent to a = a + (a + 1);
Substituting your value of a, we get a = 0 + (0 + 1);
Remember that operands in an expression are evaluated from left to right. Eric Lippert goes into evaluation order in depth here.
What does this mean in practice?
Well, if we write a = a + ++a;, a will become 1 because the first a is 0 at the time of evaluation, and then becomes 1 in ++a, meaning the overall assignment is a value of 1.
If we reverse this a little and instead write a = ++a + a; then ++a will calculate 1, and by the time we reach the second a, it's already 1, meaning that we effectively have a = 1 + 1; so we get 2.
You can verify that with the following code:
var a = 0;
a = a + ++a;
var b = 0;
b = ++b + b;
Console.WriteLine(a); // 1
Console.WriteLine(b); // 2
Try it online
I have a simple algebraic relationship that uses three variables. I can guarantee that I know two of the three and need to solve for the third, but I don't necessarily know which two of the variables I will know. I'm looking for a single method or algorithm that can handle any of the cases without a huge batch of conditionals. This may not be possible, but I would like to implement it in a more general sense rather than code in every relationship in terms of the other variables.
For example, if this were the relationship:
3x - 5y + z = 5
I don't want to code this:
function(int x, int y)
{
return 5 - 3x + 5y;
}
function(int x, int z)
{
return (5 - z - 3x)/(-5);
}
And so on. Is there a standard sort of way to handle programming problems like this? Maybe using matrices, parameterization, etc?
If you restrict yourself to the kind of linear functions shown above, you could generalize the function like this
3x - 5y + z = 5
would become
a[0]*x[0] + a[1]*x[1] + a[2]*x[2] = c
with a = { 3, -5, 1 } and c = 5.
I.e., you need a list (or array) of constant factors List<double> a; and a list of variables List<double?> x; plus the constant on the right side double c;
public double Solve(IList<double> a, IList<double?> x, double c)
{
int unknowns = 0;
int unkonwnIndex = 0; // Initialization required because the compiler is not smart
// enough to infer that unknownIndex will be initialized when
// our code reaches the return statement.
double sum = 0.0;
if (a.Count != x.Count) {
throw new ArgumentException("a[] and x[] must have same length");
}
for (int i = 0; i < a.Count; i++) {
if (x[i].HasValue) {
sum += a[i] * x[i].Value;
} else {
unknowns++;
unknownIndex = i;
}
}
if (unknowns != 1) {
throw new ArgumentException("Exactly one unknown expected");
}
return (c - sum) / a[unknownIndex];
}
Example:
3x - 5y + z = 5
5 - (- 5y + z)
x = --------------
3
As seen in the example the solution consists of subtracting the sum of all terms except the unknown term from the constant and then to divide by the factor of the unknown. Therefore my solution memorizes the index of the unknown.
You can generalize with powers like this, assuming that you have the equation
a[0]*x[0]^p[0] + a[1]*x[1]^p[1] + a[2]*x[2]^p[2] = c
you need an additional parameter IList<int> p and the result becomes
return Math.Pow((c - sum) / a[unknownIndex], 1.0 / p[unknownIndex]);
as x ^ (1/n) is equal to nth-root(x).
If you use doubles for the powers, you will even be able to represent functions like
5
7*x^3 + --- + 4*sqrt(z) = 11
y^2
a = { 7, 5, 4 }, p = { 3, -2, 0.5 }, c = 11
because
1
x^(-n) = ---
x^n
and
nth-root(x) = x^(1/n)
However, you will not be able to find the roots of true non-linear polynomials like x^2 - 5x = 7. The algorithm shown above, works only, if the unknown appears exactly once in the equation.
Yes, here is one function:
private double? ValueSolved (int? x, int? y, int? z)
{
if (y.HasValue && z.HasValue && !x.HasValue
return (5 + (5 * y.Value) - z.Value) / 3;
if (x.HasValue && z.HasValue && !y.HasValue
return (5 - z.Value - (3 * x.Value)) / -5;
if (x.HasValue && y.HasValue && !z.HasValue
return 5 - (3 * x.Value) + (5 * y.Value);
return null;
}
There is no standard way of solving such a problem.
In the general case, symbolic math is a problem solved by purpose built libraries, Math.NET has a symbolic library you might be interested in: http://symbolics.mathdotnet.com/
Ironically, a much tougher problem, a system of linear equations, can be easily solved by a computer by calculating an inverse matrix. You can set up the provided equation in this manner, but there are no built-in general purpose Matrix classes in .NET.
In your specific case, you could use something like this:
public int SolveForVar(int? x, int? y, int? z)
{
int unknownCount = 0;
int currentSum = 0;
if (x.HasValue)
currentSum += 3 * x.Value;
else
unknownCount++;
if (y.HasValue)
currentSum += -5 * y.Value;
else
unknownCount++;
if (z.HasValue)
currentSum += z.Value;
else
unknownCount++;
if (unknownCount > 1)
throw new ArgumentException("Too Many Unknowns");
return 5 - currentSum;
}
int correctY = SolveForVar(10, null, 3);
Obviously that approach gets unwieldy for large variable counts, and doesn't work if you need lots of dynamic numbers or complex operations, but it could be generalized to a certain extent.
I'm not sure what you are looking for, since the question is tagged symbolic-math but the sample code you have is producing numerical solutions, not symbolic ones.
If you want to find a numerical solution for a more general case, then define a function
f(x, y, z) = 3x - 5y + z - 5
and feed it to a general root-finding algorithm to find the value of the unknown parameter(s) that will produce a root. Most root-finding implementations allow you to lock particular function parameters to fixed values before searching for a root along the unlocked dimensions of the problem.
I have 2 int arrays.
int[] data1 #
int[] data2 #
I want to create a 3rd int[] data3 which is the differences between the 2 other arrays.
Let us take the 1st value in data1.
The value is 15 (e.g.).
Now let us take the 1st value in data2.
The value is 3 (e.g.).
The 1st value in data3 would be 12.
BUT, if the 1st values were the other way round i.e.
data1[0] = 3
data2[0] = 15
then the difference would be -12. Yet I want it to be just 12.
at the moment I have a for loop and I do the computation stuff there to get that type of result.
Is there a way to do data1-data2 = data3 without enumerating through
a loop?
If so, can I just get the differences without using minus
numbers?
Thanks
N.B.
In response to the 'closers'. I agree with you to a certain point. What I need to add to this questions is this:
I am looking for the most efficient (quickest way but low memory being 2nd priority) to facilitate this. Using Linq (as I understand it) can be the slowest approach?
You are looking for Zip method
var data3 = data1.Zip(data2, (d1,d2) => Math.Abs(d1 - d2)).ToArray();
Enumerable.Zip<TFirst, TSecond, TResult> Method
Applies a specified function to the corresponding elements of two sequences, producing a sequence of the results.
So it simply takes each corresponding element, e.g data1[0] and data2[0], then data1[1] and data2[1] so on.. then applies the function Math.Abs(d1-d2) which simply substracts two numbers and gets the absolute value of the result. Then returns a sequence which contains the result of each operation.
"Is there a way to do data1-data2 = data3 without enumerating through a loop?" No. It is technically impossible.
At best, or rather worst, you can call function that will do enumeration for you. But it will be slow. In case of LINQ, ungodly slow.
For machine I am currently working on results from other answers are as following for 4KB table (1024 integers).
23560 ticks - Giannis Paraskevopoulos. Array-Enumerable-Array conversions not too fast, Copying array via ToList().ToArray() chain is roughly 25 times slower than Array.Copy().
10198 ticks - Selman22. 2 times faster, but still slow. Lambdas are eye candy to make creating events prettier, not faster. You end up with some anonymous method laying around, which takes can eat more CPU time for call-return than its operation (remember that math we do here CPU can do in just few cycles).
566 ticks - Tim Schmelter GetDifference() function (Main culprit is JIT here, in native code and/or more often usage difference would be negligible)
27 ticks - Just a loop. 400 times faster than Zip, over 800 faster than converting array to list and back.
Loop code:
for (int i = 0; i < data3.Length; i++)
{
data3[i] = Math.Abs(data1[i] - data2[i]);
}
Such basic memory operations can be directly translated to machine code without horrible performance and humongous memory footprint of LINQ.
Moral of the story is: LINQ is for readability (which in this case is arguable) not for performance (which in this case is noticeable).
Optimization time! Lets abuse our CPU a tiny bit.
Unroll loop. Or do not. Your experience may vary. Even in
assembler itself loop unrolling performance gain or lose vary
greatly in same family of processors. New CPU's and compilers are
aware of old tricks and simply implement them on their own. For
i3-3220 I tested code on loop unroll to 4 lines resulted in faster
execution on 32bit code but on 64bit it was a bit slower while unroll to 8 was opposite.
Compile for x64. As we are here working on 32bit data we won't make
use of 64bit registers... or will we? On x86 less than half of
registers are truly available to generated code (in assembly written
by hand you can always squeeze out more), on x64 however you get eight bonus registers which are free to use. The more you can do without accessing memory, the faster your code. In this case speed gain is at about 20%.
Close Visual Studio. Do not speed-test 64 bit code in 32bit IDE
(there is no 64bit version as for now, and probably wont be for
long time). It will make x64 code roughly two times slower due
to architecture mismatch. (Well... you should never speed-test code under debugger anyway...)
Do not use built-in functions too much. In this case Math.Abs have
overhead hidden inside. For some reasons (which will need analyze of IL to find out), checking for negative values was faster with ?: than with If-Else. Such check saved a lot of time.
UPDATE: ?: is faster than If-Else due to differences in resulting machine code... at least for just comparing two values. Its machine code is much less weird than If-Else (which does not look like what you would write "by-hand"). Apparently it is not just different form of writing If-Else statement but fully separate command optimized for simple conditional assignment.
Resulting code was roughly 8 times faster than simple loop with Math.Abs(); Remember you can unroll loop only to divisors of your dataset size. You wrote that your dataset size is 25920, so 8 is fine. (max is 64, but I doubt it would have any sense to go that high). I suggest hiding this code in some function as it is fugly.
int[] data3 = new int[data1.Length];
for (int i = 0; i < data1.Length; i += 8)
{
int b;
b = (data1[i + 0] - data2[i + 0]);
data3[i + 0] = b < 0 ? -b : b;
b = (data1[i + 1] - data2[i + 1]);
data3[i + 1] = b < 0 ? -b : b;
b = (data1[i + 2] - data2[i + 2]);
data3[i + 2] = b < 0 ? -b : b;
b = (data1[i + 3] - data2[i + 3]);
data3[i + 3] = b < 0 ? -b : b;
b = (data1[i + 3] - data2[i + 4]);
data3[i + 4] = b < 0 ? -b : b;
b = (data1[i + 5] - data2[i + 5]);
data3[i + 5] = b < 0 ? -b : b;
b = (data1[i + 6] - data2[i + 6]);
data3[i + 6] = b < 0 ? -b : b;
b = (data1[i + 7] - data2[i + 7]);
data3[i + 7] = b < 0 ? -b : b;
}
This is not even its final form. I will try to do some more heretic tricks on it.
BitHack's, low level cheats!
As I mentioned, there was still place for improvements.
After cutting out LINQ, main ticks munchkin was Abs(). When it was removed from code we got left with contest between IF-ELSE and shorthand ?: operator.
Both are branching operators, which once in the past were widely known as being slower than linear code. Currently ease of use/writing tend to be picked over performance (sometimes correctly, sometimes incorrectly).
So lets make our branching condition linear. It is possible by abusing fact that branching in this code contains math operating on just single variable. So lets make code equivalent of this.
Now do you remember how to negate Two's complement number?, negate all bits and add one. Lets do it in one line without conditions then!
It is bitwise operators time to shine. OR and AND are boring, real men use XOR. Whats so cool about XOR? Aside of its usual behavior you can also turn it into NOT (negation) and NOP (no-operation).
1 XOR 1 = 0
0 XOR 1 = 1
so XOR'ing by value filled with only 1's gives you NOT operation.
1 XOR 0 = 1
0 XOR 0 = 0
so XOR'ing by value filled with only 0's does nothing at all.
We can obtain sign from our number. For 32bit integer it is as simple as x>>31. It moves bit sign to lowest bit. As even wiki will tell you, bits inserted from left will be zeros, so you result of x>>31 will be 1 for negative number (x<0) and 0 for non-negative (x>=0), right?
Nope. For signed values Arithmetic shift is used over plain bit-shift. So we will get -1 or 0 depending on sign.... which means that 'x>>31' will give 111...111 for negative and 000...000 for non-negative. If you will XOR original x by result of such shift you will perform NOT or NOP depending on value sign. Another useful thing is that 0 will result in NOP for addition/negation so we can add/subtract -1 depending on value sign.
So 'x^(x>>31)' will flip bits of negative number while making no changes to non-negative and 'x-(x>>31)' will add 1 (negated negative value gives positive) to negative x and make no changes to non-negative value.
When combined you get '(x ^ (x >> 31)) - (x >> 31)'... which can be translated to:
IF X<0
X=!X+1
and it is just
IF X<0
X=-X
How does it affect performance?
Our XorAbs() requires just four basic integer operations with one load and one store. Branching operator itself takes about as much CPU ticks. And while modern CPU's are great at doing branch-predicting, they are still faster by simply not doing it when feed sequential code.
And whats the score?
Roughly four times faster than built-in Abs();
About twice as fast as previous code (versions without unrolling)
Depending on CPU it can get better result without loop-unrolling.
Due to elimination of code branching CPU can "unroll" loop on its
own. (Haswells are weird with unrolling)
Resulting code:
for (int i = 0; i < data1.Length; i++)
{
int x = data1[i] - data2[i];
data3[i] = (x ^ (x >> 31)) - (x >> 31);
}
Parallelism and Cache usage
CPU have super fast Cache memory, when processing an array sequentially it will copy whole chunks of it to cache.
But if you write crappy code you will get cache misses. You can easily fall into this trap by screwing up order of nested loops.
Parallelism (multiple threads, same data) must works on sequential chunks in order to make good use of cpu cache.
Writing threads by hand will allow you to pick chunks for threads manually, but it is bothersome way.
Since 4.0 .NET comes with helpers for that, however default Parallel.For makes a mess of cache.
So this code is actually slower than its single thread version due to cache-miss.
Parallel.For(0, data1.Length,
fn =>
{
int x = data1[fn] - data2[fn];
data3[fn] = (x ^ (x >> 31)) - (x >> 31);
}
It is possible to make manual use of cached data by performing sequential operation in it. For example you can unroll loop, but its dirty hack and unrolling have its own performance issues (it depends on CPU model).
Parallel.For(0, data1.Length >> 3,
i =>
{
int b;
b = (data1[i + 0] - data2[i + 0]);
data3[i + 0] = b < 0 ? (b ^ -1) + b : b;
b = (data1[i + 1] - data2[i + 1]);
data3[i + 1] = b < 0 ? (b ^ -1) + b : b;
b = (data1[i + 2] - data2[i + 2]);
data3[i + 2] = b < 0 ? (b ^ -1) + b : b;
b = (data1[i + 3] - data2[i + 3]);
data3[i + 3] = b < 0 ? (b ^ -1) + b : b;
b = (data1[i + 3] - data2[i + 4]);
data3[i + 4] = b < 0 ? (b ^ -1) + b : b;
b = (data1[i + 5] - data2[i + 5]);
data3[i + 5] = b < 0 ? (b ^ -1) + b : b;
b = (data1[i + 6] - data2[i + 6]);
data3[i + 6] = b < 0 ? (b ^ -1) + b : b;
b = (data1[i + 7] - data2[i + 7]);
data3[i + 7] = b < 0 ? (b ^ -1) + b : b;
}
However .NET also have Parrarel.ForEach and Load Balancing Partitioners.
By using both of them you get best of all worlds:
dataset size independent code
short, neat code
multithreading
good cache usage
So final code would be:
var rangePartitioner = Partitioner.Create(0, data1.Length);
Parallel.ForEach(rangePartitioner, (range, loopState)
=>
{
for (int i = range.Item1; i < range.Item2; i++)
{
int x = data1[i] - data2[i];
data3[i] = (x ^ (x >> 31)) - (x >> 31);
}
});
It is far from maximum CPU usage (which is more complicated than just maxing its clock, there are multiple cache levels, several pipelines and much more) but it is readable, fast and platform independent (except integer size, but C# int is alias to System.Int32 so we are safe here).
Here I think we will stop with optimization.
It came out as an article rather than answer, I hope no one will purge me for it.
Here is another (less readable but maybe a little bit more efficient) approach that does not need LINQ:
public static int[] GetDifference(int[] first, int[] second)
{
int commonLength = Math.Min(first.Length, second.Length);
int[] diff = new int[commonLength];
for (int i = 0; i < commonLength; i++)
diff[i] = Math.Abs(first[i] - second[i]);
return diff;
}
Why little bit more efficient? Because ToArray has to resize the array until it knows the final size.
var data3 = data1.Select((x,i)=>new {x,i})
.Join
(
data2.Select((x,i)=>new {x,i}),
x=>x.i,
x=>x.i,
(d1,d2)=>Math.Abs(d1.x-d2.x)
)
.ToArray();
if x = 3 and z is unassigned,
why does z = x-- - --x evaluates to 2?
my professor is lecturing about this at the moment, and I'm currently stuck with this dilemma. Unfortunately, no one can explain why it happens.
on x--, x = 3, and after that it's 2.
on --x, x = 1, because substraction (from 2) is done beforehand.
Therefore, 3 - 1 = 2.
Here is the order of operations, illustrated for better understanding:
x-- - --x Hold value of x (lets call it tmpA). tmpA is 3.
x-- - --x Decreases x. It is now 2.
x-- - --x Decreases x. It is now 1.
x-- - --x Hold value of x (lets call it tmpB). tmpB is 1.
x-- - --x Performs substruction from calculated values. 3 - 1 = 2.
The -- prefix means the decrement will be done before evaluating the expression and the postfix -- means the decrement will be done after evaluation the expression.
Ok, its pretty simple:
let's add brackets:
z = ( x-- ) - ( --x )
^^ this is how compiler sees your code after tokenizing.
Compiler evaluates equation (right part) from left to right
Now,
x-- is equal to POP the value of x and then decrement it and PUSH back value into a memory. Ok, lets do it:
Current value of X is 3, decremented is 2 - so, in equation we'll get 3, but X will contain new value 2.
--x is equal to decrement X value and then POP this value into equation. Let's do it:
Current value of X is 2 (because previous operation decremented it), and now we want to decrease it once again. 2-1 = 1, got it.
Now, back to whole equation: z = (3) - (1) = 2.