The name 'Fix' does not exist in the current context - c#

In my project I am converting some vb.net to c# and I came to this line:
int thisdigit = Fix(countervalue / (Math.Pow(10, (numdigits - j - 1)))) - Fix(countervalue / (Math.Pow(10, (numdigits - j)))) * 10;
But I get the error:
The name 'Fix' does not exist in the current context
How do I fix this? I can't understand why Fix() wouldn't exist.
But if I used Math.Truncate() instead, well, that doesn't work because thisdigit is an int.
How could I change that?
Here is my original vb.net code:
dim dg as int
dg = Fix(value / (10 ^ (digits - j - 1))) - Fix(value / (10 ^ (digits - j))) * 10
Here is a link to what I'm trying to convert:
https://www.developerfusion.com/code/3734/aspnet-graphical-page-hit-counter/
The code works in my vb.net projects. I've run my converted code through the debugger, and the only place I can see any problem is with this line.
I came up with this, too:
double thisdigit = Math.Truncate((double)(countervalue / (10 ^ (numdigits - j - 1)))) - Math.Truncate(((double)(countervalue / (10 ^ (numdigits - j))) * 10));

I don't really understand why this is so convoluted..
The original code seems to draw a counter, one digit at a time:
dim j as Integer, dg as Integer
for j = 0 to (digits-1)
' Extract digit from value
dg = fix(value / (10^(digits - j - 1))) - fix(value / (10^(digits - j)))*10
' Add digit to the output graphic
g.drawimage(i, New rectangle(j*dgwidth, 0, dgwidth, dgheight), New rectangle(dg*dgwidth, 0, dgwidth, dgheight), GraphicsUnit.Pixel)
next j
But surely it would just be easier to do something like:
int pageCounter = 7234283;
string toDraw = pageCounter.ToString();
for(int i = 0; i < toDraw.Length; i++)
someGraphics.DrawString(toDraw.Substring(i, 1), someFont, someBrush, new PointF(i * 10.0f, 0));
Or perhaps:
int pageCounter = 7234283;
string toDraw = pageCounter.ToString();
PointF p = new PointF(0.0f, 0.0f);
foreach(char c in toDraw){
someGraphics.DrawString(c.ToString(), someFont, someBrush, p);
p.X += 10.0f;
}

With some help from Aidy in the C# Discord, I ended up with this. Very simple and clean.
//Get the number of digits to display in the output graphic
//If the countervalue is 16 then "16".ToString("D5") converts it to "00016".
//ToCharArray() turns that into an array of characters ['0', '0', '0', '1', '6'].
//We loop through that list and convert the char back to int and we get 0, 0, 0, 1 and 6.
//Thanks to #Aidy in the C# Discord for help on this
int numdigits = Convert.ToInt32(Request.QueryString["digits"]);
var digits = countervalue.ToString("D" + numdigits.ToString()).ToCharArray();
//Create an output object
Bitmap imageoutput = new Bitmap(digitwidth * digits.Length, digitheight, PixelFormat.Format24bppRgb); //should be 5*15 = 75 for digits.gif
Graphics graphic = Graphics.FromImage(imageoutput); //here is our black box
//digits.gif is 150 x 20px;
//So, if our countervalue = 16, and numdigits = 5, we want to display 00016.
for(int j = 0; j < digits.Length; j++) {
//We loop through that digits and convert the char back to int and we get 0, 0, 0, 1 and 6.
int thisdigitX = int.Parse(digits[j].ToString());
//add the digit to the output graphic
graphic.DrawImage(digitpix, new Rectangle(j * digitwidth, 0, digitwidth, digitheight), new Rectangle(thisdigitX * digitwidth, 0, digitwidth, digitheight), GraphicsUnit.Pixel);
}
However, I was also able to get the original code to work with the conversion of int and double and importing the Visual Basic assembly.
using Microsoft.VisualBasic;
int thisdigitX = Conversion.Fix(countervalue / ((int)Math.Pow(10, (double)(numdigits - j - 1)))) - ( Conversion.Fix(countervalue / ((int)Math.Pow(10,(double)(numdigits - j)))) * 10);
Here is a link to my github page where I've posted the entire working project if anyone is really interested. (not self-promoting here - just sharing; I don't care if anyone uses it or not).

Related

How use bitmask operator

I'm learning bit mask. And found and example but couldn't make it work.
I'm trying to calculate all sum combination from one array.
The result should be
0 - 1 - 2 - 3 - 3 - 4 - 5 - 6
My problem is with (i & mask) should only result in {0,1} and isn't.
Instead is producing.
0 - 1 - 4 - 5 - 12 - 13 - 16 - 17
int[] elem = new int[] { 1, 2, 3 };
double maxElem = Math.Pow(2, elem.Length);
for (int i = 0; i < maxElem; first++)
{
int mask = 1, sum = 0;
for (int run = 0; run < elem.Length; run++)
{
sum += elem[run] * (i & mask);
mask <<= 1;
}
Debug.Write(sum + " - ");
}
(i & mask) should only result in {0,1} and isn't
(i & mask) should return a result in {0,1} only when mask is 1 - that is, on the initial iteration. However, as soon as mask gets shifted by mask <<= 1 operation, the result of the next operation will be in {0,2}. As the mask gets shifted, possible results will become {0,4}, {0,8}, {0,16} and so on, because the only bit set to 1 in the mask would be moving to the left.
The reason why << operator doubles the number is the same as the reason why writing a zero after a decimal number has the effect of multiplying the number by ten: appending a zero to a number of any base is the same as multiplying that number by the value of base.
Ok, I solve it creating an IF.
int[] elem = new int[] { 1, 2, 3 };
double maxElem = Math.Pow(2, elem.Length);
for (int i = 0; i < maxElem; first++)
{
for (int run = 0; run < elem.Length; run++)
{
int mask = 1, sum = 0;
if ((i & mask) > 0) // ADD THIS LINE
{
sum += elem[run];
}
mask <<= 1;
}
}

Result not matching. Floating point error?

I am trying to rewrite the R function acf that computes Auto-Correlation into C#:
class AC
{
static void Main(string[] args)
{
double[] y = new double[] { 772.9, 909.4, 1080.3, 1276.2, 1380.6, 1354.8, 1096.9, 1066.7, 1108.7, 1109, 1203.7, 1328.2, 1380, 1435.3, 1416.2, 1494.9, 1525.6, 1551.1, 1539.2, 1629.1, 1665.3, 1708.7, 1799.4, 1873.3, 1973.3, 2087.6, 2208.3, 2271.4, 2365.6, 2423.3, 2416.2, 2484.8, 2608.5, 2744.1, 2729.3, 2695, 2826.7, 2958.6, 3115.2, 3192.4, 3187.1, 3248.8, 3166, 3279.1, 3489.9, 3585.2, 3676.5 };
Console.WriteLine(String.Join("\n", acf(y, 17)));
Console.Read();
}
public static double[] acf(double[] series, int maxlag)
{
List<double> acf_values = new List<double>();
float flen = (float)series.Length;
float xbar = ((float)series.Sum()) / flen;
int N = series.Length;
double variance = 0.0;
for (int j = 0; j < N; j++)
{
variance += (series[j] - xbar)*(series[j] - xbar);
}
variance = variance / N;
for (int lag = 0; lag < maxlag + 1; lag++)
{
if (lag == 0)
{
acf_values.Add(1.0);
continue;
}
double autocv = 0.0;
for (int k = 0; k < N - lag; k++)
{
autocv += (series[k] - xbar) * (series[lag + k] - xbar);
}
autocv = autocv / (N - lag);
acf_values.Add(autocv / variance);
}
return acf_values.ToArray();
}
}
I have two problems with this code:
For large arrays (length = 25000), this code takes about 1-2 seconds whereas R's acf function returns in less than 200 ms.
The output does not match R's output exactly.
Any suggestions on where I messed up or any optimizations to the code?
C# R
1 1 1
2 0.945805846 0.925682317
3 0.89060465 0.85270658
4 0.840762283 0.787096604
5 0.806487301 0.737850083
6 0.780259665 0.697253317
7 0.7433111 0.648420319
8 0.690344341 0.587527097
9 0.625632533 0.519141887
10 0.556860982 0.450228026
11 0.488922355 0.38489632
12 0.425406196 0.325843042
13 0.367735169 0.273845337
14 0.299647764 0.216766466
15 0.22344712 0.156888402
16 0.14575994 0.099240809
17 0.072389526 0.047746281
18 -0.003238526 -0.002067146
You might try changing this line:
autocv = autocv / (N - lag);
to this:
autocv = autocv / N;
Either of these is an acceptable divisor for the expected value, and R is clearly using the second one.
To see this without having access to a C# compiler, we can read in the table that you have, and adjust the values by dividing each value in the C# column by N/(N - lag), and see that they agree with the values from R.
N is 47 here, and lag ranges from 0 to 17, so N - lag is 47:30.
After copying the table above into my local clipboard:
cr <- read.table(file='clipboard', comment='', check.names=FALSE)
cr$adj <- cr[[1]]/47*(47:30)
max(abs(cr$R - cr$adj))
## [1] 2.2766e-09
A much closer approximation.
You might do better if you define flen and xbar as type double as floats do not have 9 decimal digits of precision.
The reason that R is so much faster is that acf is implemented as native and non-managed code (either C or FORTRAN).

C# math statement not working while doing it in parts works

I am wondering if this could be some kind of associativity problem, because when I do the problem on paper, I get the correct answer, but when I run the code I keep getting 4 over and over. Here is the code. Why aren't these equal? What am I missing?
The whole problem (returns 4 on every iteration):
for (int x = 1; x <= stackCount; x++) {
temp = ((x - 1) / stackCount * uBound) + lBound + 1;
Base[x] = Top[x] = Convert.ToInt32(Math.Floor(temp));
}
Broken into pieces (runs correctly):
double temp, temp1, temp2, temp3, temp4;
for (int x = 1; x <= stackCount; x++) {
temp1 = (x - 1);
temp2 = temp1 / stackCount;
temp3 = temp2 * uBound;
temp4 = temp3 + lBound + 1;
Base[x] = Top[x] = Convert.ToInt32(Math.Floor(temp4));
}
Added:
Yes, I am sorry, I forgot about that declarations:
//the main memory for the application
private string[] Memory;
//arrays to keep track of the bottom and top of stacks
private int[] Base;
private int[] Top;
//keep track of the upper and lower bounds and usable size
private int LowerBound;
private int UpperBound;
private int usableSize;
I also think I had that backwards. I thought that if you used a double in a division operation with integers that the result would be a double, but it appears that is not the case. That makes sense! Thank you all!
Speculation: stackCount, uBound, and lBound are all integers or longs.
Result: The entire expression is computed as though you're doing integer arithmetic.
Solution: temp = ((double)(x -1) / stackCount * uBound) + lBound + 1;
You haven't given us the full code. In particular, the declarations for stackCount, uBound and lBound and temp have all been omitted. You've also omitted the values of the first 3.
If, as seems likely, all the bits involved in your expression
((x - 1) / stackCount * uBound) + lBound + 1;
are integral types, the result will also be an integral type since integer division is performed:
int x = 9 ;
int y = 4 ;
double z = x / y ;
yields the expected double precision value 2.0.
((5 - 1) / 9 * 11) + 3 + 1
The particular integral type that the expression resolves two is depends on the various types involved and whether or not they are signed, and whether or not they are all compatible.

C# object null reference exception - not sure how to set array values

I guess I'm not setting the array correctly or something, but this throws a "nullreferenceexception" when it gets to the line where it actually sets the new array value to the color_table array (should be the 7th and 12th lines of what you see below). How should I write this so that it works?
public int[] colors = new int[] { 0, 255, 0, 255, 0, 255 };
private int[][] color_table;
public void setcolors()
{
this.color_table[0] = new int[] { 0, 0, 0 };
for (int i = 1; i <= this.precision; i++) {
int r = (((this.colors[1] - this.colors[0]) * ((i - 1) / (this.precision - 1))) + this.colors[0]);
int g = (((this.colors[3] - this.colors[2]) * ((i - 1) / (this.precision - 1))) + this.colors[2]);
int b = (((this.colors[5] - this.colors[4]) * ((i - 1) / (this.precision - 1))) + this.colors[4]);
this.color_table[i] = new int[] { r, g, b };
}
}
I've heard something about that you MUST initialize an array with its length before using it, but a) I don't know how to do that and b) I'm not sure if it's problem. The issue there is that I don't know what the array length is going to be. I tried this to no avail:
private int[this.precision][3] color_table;
Thanks!
this.color_table has not been initialized. Hence you can't assign values to it.
Did you mean something like this:
public void setcolors()
{
color_table = new int[precision + 1][];
for (int i = 1; i <= this.precision; i++)
{
int r = (((this.colors[1] - this.colors[0]) * ((i - 1) / (this.precision - 1))) + this.colors[0]);
int g = (((this.colors[3] - this.colors[2]) * ((i - 1) / (this.precision - 1))) + this.colors[2]);
int b = (((this.colors[5] - this.colors[4]) * ((i - 1) / (this.precision - 1))) + this.colors[4]);
this.color_table[i] = new int[] { r, g, b };
}
}
try to use list if you don't know the length of your array
List<int[]> color_table = new List<int[]>();
...
color_table.Add(new int[] { r, g, b });

Calculating RMS with overlapping windows

I have a 1-dimensional float array of root mean square values, each calculated with the same window length. Let's say
RMS = {0, 0.01, 0.4, ... }
Now the RMS for a larger window, which can be represented as a range of the original windows, can be calculated as the RMS of the "participating" RMS values from RMS[i] to RMS[i + len]. Here len is the length of the larger window divided by the lenght of the original windows.
I'd like to create a rolling window. I want
rollingRMS[0] = RMS from 0 to len
...
rollingRMS[n] = RMS from n to len+n
calculated as efficiently as possible. I know this isn't very hard to crack, but does anyone have ready code for this?
EDIT: I asked for sample code, so I guess it would be decent to provide some. The following is based on pierr's answer and is written in C#. It's a bit different from my original question as I realized it would be nice to have the resulting array to have the same size as the original and to have the windows end at each element.
// The RMS data to be analysed
float[] RMS = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// The resulting rolling RMS values
float[] rollingRMS = new float[RMS.Length];
// Window lenght
int len = 3;
// Calculate: rollingRMS will hold root mean square from windows which end at
// each respective sample in the RMS array. For the first len samples the input
// will be treated as zero-padded
for (int i = 0; i < RMS.Length; i++)
{
if (i == 0)
rollingRMS[i] = (float)Math.Sqrt((RMS[i] * RMS[i] / len));
else if (i < len)
rollingRMS[i] = (float)Math.Sqrt(
( RMS[i] * RMS[i] +
len * (rollingRMS[i - 1] * rollingRMS[i - 1])
) / len);
else
rollingRMS[i] = (float)Math.Sqrt(
( len * (rollingRMS[i - 1] * rollingRMS[i - 1]) +
RMS[i] * RMS[i] -
RMS[i - len] * RMS[i - len]
) / len);
}
I am not sure that I have understood your problem correctly. But let me have a try.
a=[1,2,3,4,5,6,7,8,9,10]
LEN = 3
SquareOfRollingRMS[0] = (a[0]^2 + a[1]^2 + a[2]^2 ) / LEN
SquareOfRollingRMS[1] = ( a[1]^2 + a[2]^2 + a[3]^2 ) / LEN
It's not difficult to notice that:
SquareOfRollingRMS[i] = RollingRMS[i-1] * LEN - a[i-1]^2 + a[i+LEN-1]^2
RollingRMS[i] = SqurefOfRollingRMS[i]^(1/2)
Doing it this way ,you are avoiding recaculating the overlap windows.
EDIT:
You can save some divide and multiply operation by moving LEN to the left side of the equations. This might speed up a lot as dividing is usually relatively slow.
LEN_by_SquareOfRollingRMS[0] = (a[0]^2 + a[1]^2 + a[2]^2)
LEN_by_SquareOfRollingRMS[i] = LEN_by_RollingRMS[i-1] - a[i-1]^2 + a[i+LEN-1]^2

Categories

Resources