Confused about accessing elements from IntPtr in C# [closed] - c#

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I am using Kinect v2 which contains the following CameraSpacePoint struct:
public struct CameraSpacePoint : IEquatable<CameraSpacePoint>
{
public float X;
public float Y;
public float Z;
}
The CameraSpacePoint also contains few methods Equals, GetHashCode etc, which are not shown above to keep the post clean and short.
Well, I define cameraSpacePoints in class constructor as follows:
IntPtr cameraSpacePoints = Marshal.AllocHGlobal(512 * 424 * 4 * 3);
Below is the explanation of above memory allocation:
512: width
424: height
4: bytes needed for single 'float'
3: total three variables i.e., 'X', 'Y' and 'Z'
Later, I copied values to cameraSpacePoints using CoordinateMapper as follows:
coordinateMapper.MapDepthFrameToCameraSpaceUsingIntPtr(depthFrameData,
512 * 424 * 2,
cameraSpacePoints,
512 * 424 * 4 * 3);
It seems perfect. Now I want to get the values from cameraSpacePoints. So I used following code inside unsafe block:
float* cameraSpacePoint = (float*)cameraSpacePoints;
for (var index = 0; index < 512 * 424; index++)
{
float X = cameraSpacePoint[index];
float Y = cameraSpacePoint[index + 1];
float Z = cameraSpacePoint[index + 2];
}
It doesn't seem working which I realized while visualizing it. It appears to me that there is some confusion while accessing elements from cameraSapacePoints using IntPtr. What is missing here? Any suggestions, please?

In your initial code, you are casting the IntPtr (which points to an array[] of CameraSpacePoint) to a raw float pointer. If you interpret the IntPtr as raw floats, since you are handling 3 points at a time (x, y and z), you'll need to increment the loop by 3 floats each time, e.g. (I've renamed variables for clarity):
var floats = (float*)cameraSpacePoints;
for (var index = 0; index < 512 * 424; index+=3)
{
var x = floats[index];
var y = floats[index + 1];
var z = floats[index + 2];
var myCameraSpacePoint = new CameraSpacePoint
{
X = x,
Y = y,
Z = z
};
// use myCameraSpacePoint here
}
But that's a horribly inefficient way of handling the data, given that the data was originally a CameraSpacePoint in any event. Much better would just be to cast the struct directly back to the actual type:
var cameraSpacePoints = (CameraSpacePoint*)cameraSpacePoints;
for (var index = 0; index < 512 * 424; index++)
{
var cameraSpacePoint = cameraSpacePoints[index];
// Do something with cameraSpacePoint
}
By casting to the correct type (CameraSpacePoint), we're also improving the robustness of the code - e.g. if, in future, additional fields are added to a new version of CameraSpacePoint, then a recompile of your code against the new version will again work, whereas accessing the floats directly would break the encapsulation and make maintenance difficult.
The reason why we no longer need to increment the loop by 3, is because when we use the subscript / index operation on cameraSpacePoints[index], is that the compiler knows to find element n at an offset of n * sizeof(CameraSpacePoint) after the position of the initial cameraSpacePoints[0]. And sizeof(CameraSpacePoint) is the size of 3 floats.

Related

C# Interpolating small array into larger array

I have two arrays of doubles X and Y of same size (any size is possible).
The difference between x-points is always stable. For example X[1]-X[0] = X[2]-X[1]...
These two arrays together form a curve (say C1) of (x[i],y[i]) points.
I have another another fixed curve C2 shown in the figure:
x-limit , y-limit
(0) ,(-5)
(1e9) ,(-5)
(2e9) ,(-6.5)
(3e9) ,(-9.2)
(6e9) ,(-16.5)
(12e9) ,(-29)
I want to be able to check if C1 hits or crosses under C2 but I can't do that due to the difference in size.
What I thought of is interpolating the arrays of C2 of size 6 into arrays of size equal to the size of the arrays of C1
This way I would have two Y-arrays of same size (one from C1 and one from C2) and I can check for the difference. (If negative then it is below the limit)
My question is what can I use to interpolate the small array into a larger one keeping into consideration the difference between y-points, and is there any other way I could use to check is my initial arrays exceed the limit.
If there anything I could add that is not clear let me know and thank you.
Rather than storing interpolated points, I would calculate and use them on the fly.
Assuming that the points to be compared are sorted in ascending order, I would proceed as follows:
double limitX1 = limitX[0];
double limitY1 = limitY[0];
// Create fake point to the left
double limitX0 = -2;
double limitY0 = limitY1;
double f = 0.0;
int actualLimitIndex = 0;
for (int i = 0; i < x.Length; i++) {
double x = x[i];
double y = y[i];
// Get current limit section
while (x > limitX1) {
actualLimitIndex++;
limitX0 = limitX1;
limitY0 = limitY1;
limitX1 = limitX[actualLimitIndex];
limitY1 = limitY[actualLimitIndex];
f = (limitY1 - limitY0) / (limitX1 - limitX0);
}
// Interpolate limit
limitY = limitY0 + (x - limitX0) * f;
// Do whatever you have to do here.
if (y > limitY) {
// We are above limit
} else {
// We are at or below limit
}
}
This also assumes that no x-value is below the minimum or above the maximum x-limit. Add additional checks if this can be the case.
This uses a linear interpolation. See: Linear interpolation (Wikipedia).

For loop with a mathemtical expression involved [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
I am trying to utilize the Math.Cos() function in c# to print a range of of values from 0 to 2pi increasing by .1pi, so 20 iterations. The problem is I cannot get my x value to change as the for loop is executing.
public void Cos()
{
double x = 0;
double a = Math.PI * x;
double b = Math.Cos(a);
for (int i = 0; i < 21; i++)
{
Console.WriteLine("Cos({0})pi = {1}", x, b);
x += .1;
}
}
When I print the results to the console, it only remembers the value of cos at x = 0. So I just get 1, 20 times as a result for Cos(.1)pi, Cos(.2)pi, etc...
I am trying to utilize the Math.Cos() function in c# to print a range of of values from 0 to 2PI increasing by .1PI
This sounds like a job for a for loop, where we start with a value of 0, and increment by .1 * PI on each iteration until it reaches 2 * PI.
Since a for loop has an initializer part, a condition part, and an incrementing part, it is the perfect construct. No need for an extra variable that increments from 0 to 20 - we can use the for loop to do our incrementing of x and our testing the exit condition!
public static void Cos()
{
for (double x = 0; x <= Math.PI * 2; x += Math.PI * .1)
{
Console.WriteLine("Cos({0})PI = {1}", x, Math.Cos(x));
}
}

Is this autocorrelation formula correctly programmed?

I am trying to implement a pitch detection algorithm from a paper, but the level of math in the paper is a few notches too advanced for me... for now.
I just want to make sure that I've understood it correctly.
I also added comment to my code that asks a question which confuses me.
The paper can be found here: https://pdfs.semanticscholar.org/0124/09d447691fd74c49bc407b3818b4617641b2.pdf
And the formula can be found on the upper right side of the second page.
My code looks like this.
public int L = 0.1f;
public float calcAutocorrelation(float[] frame)
int N = frame.Length; //frame size
float result = 0f;
for (var n = 0; n < N; n++){
result += frame[n] * frame[n + L] //in programming this is not possible as L is a float but formula says this is needed???
/* I could cast the L to an INT type but the paper states
* that L should range between 0 and 1, and in-code we'll
* probably end up with L rounded to 0 most of the time.
*/
}
return result;
}
What have I missed and what could be done better?
EDIT
Fixed and simplified the code.
public int Lag = 1;
public float calcAutocorrelation(float[] frame)
int N = frame.Length; //frame size
float result = 0f;
for (var n = 0; n < N; n++)
result += frame[n] * frame[n + Lag]
return result;
}
EDIT 2
So apparently the result sometimes end up as a NaN type, which I have a hard time figuring out.
I hacked together a simple solution like the code below, but that's not really a fix, it's just a bypass which would not give the correct result desired.
I tested my code with a small frame of 16 floats and the frame contains no NaN values what so ever. Either I'm stupid or I'm stupid because I can not for the life of me figure out what's going on.
Test Frame:
frame[0] : 0
frame[1] : 0
frame[2] : 96
frame[3] : 185
frame[4] : 0
frame[5] : 0
frame[6] : 0
frame[7] : 185
frame[8] : 0
frame[9] : 0
frame[10] : 192
frame[11] : 184
frame[12] : 0
frame[13] : 0
frame[14] : 0
frame[15] : 184
Code:
public int lag = 1;
public float calcAutocorrelation(float[] frame){
float result = 0f;
for (int i = 0; i < frame.Length - lag; i++){
float a = frame[i];
if ( float.isNaN(a) )
a = 0;
int b_idx = (i + lag);
float b = frame[b_idx];
if ( float.isNaN(b) )
b = 0;
result += a * b;
}
return 0f - result; //just inverting the results for my purposes. Doesn't really affect the end goal.
}
QUESTION
So how come b is NaN when b_idx = 7 and frame[7] is 185?
This absolutely boggles my mind!
Here's a screenshot of what's happening on my end:
EDIT 3
Found the problem regarding the NaN issue.
It seems to not be a problem at all (I think) and can be handled with a check&correct using float.isNaN().
The reason the frame is casted as a byte array is because of how the underlying audio library NAudio handles the conversion.
Read about it here: http://mark-dot-net.blogspot.com/2008/06/wavebuffer-casting-byte-arrays-to-float.html
So even though it shows up as a byte array, each value will be casted to a float correctly when working with it.
Weird, but true. Personally, that type of coding should be illegal by law, jk.
So, everything seems to be working (I think?), how is my implementation of the formula performing?
Well, the paper states the following at page 6 under Fig 6:
One of the experiments conducted was applying the PDA on /a/
utterances from the KayPENTAX Elemetrics voice database consists of 50
normal voices and 100 functional and organic voice disorders.
I recorded my own /a/ vowel and gave it a run, and this is what is plotted on my screen:
Fig 1a on page 2 of the paper
Comparing my results to Fig 1a on page 2 of the paper we can see strong similarities, but I am still not sure if I've implemented the formula correctly, because the formula I want to implement should resemble figure 1b or 1c.
I think the issue now is where the formula variable i should be in terms of code.
The paper states on page two the following:
i = The first sample inside a frame n
so... hmmm...
I think you just need to fix the condition in your for loop, so in the last cycle, it doesn't go out of bounds:
public int Lag = 1;
public float CalcAutocorrelation(float[] frame)
{
int N = frame.Length; //frame size
float result = 0;
for (int n = 0; n < N - Lag; n++)
result += frame[n] * frame[n + Lag];
return result;
}
(Note I've changed the for condition).
If you are getting NaN errors, you can check that like this:
for (int n = 0; n < N - Lag; n++)
{
result += frame[n] * frame[n + Lag];
if (float.IsNaN(result))
{
var v1 = frame[n];
var v2 = frame[n + Lag];
}
}
Just place a breakpoint inside that if and see what's going on. That should help you find a problem inside your array. Once that's fixed, you can remove that check and restore the code above.

Is there general method to solve for a single unknown if the unknown variable changes?

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.

Why doesn't this overflow?

Given this code:
int x = 20000;
int y = 20000;
int z = 40000;
// Why is it printing WTF? Isn't 40,000 > 32,767?
if ((x + y) == z) Console.WriteLine("WTF?");
And knowing an int can hold −32,768 to +32,767. Why doesn't this cause an overflow?
In C#, the int type is mapped to the Int32 type, which is always 32-bits, signed.
Even if you use short, it still won't overflow because short + short returns an int by default. If you cast this int to short - (short)(x + y) - you'll get an overflowed value. You won't get an exception though. You can use checked behavior to get an exception:
using System;
namespace TestOverflow
{
class Program
{
static void Main(string[] args)
{
short x = 20000;
short y = 20000;
short z;
Console.WriteLine("Overflowing with default behavior...");
z = (short)(x + y);
Console.WriteLine("Okay! Value is {0}. Press any key to overflow " +
"with 'checked' keyword.", z);
Console.ReadKey(true);
z = checked((short)(x + y));
}
}
}
You can find information about checked (and unchecked) on MSDN. It basically boils down to performance, because checking for overflow is a little bit slower than ignoring it (and that's why the default behavior is usually unchecked, but I bet that in some compilers/configurations you'll get an exception on the first z assignment.)
http://msdn.microsoft.com/en-us/library/5kzh1b5w.aspx
Type: int
Range: -2,147,483,648 to 2,147,483,647
While everyone is correct in saying that an "int" type on a 32 bit machine is most likely 2^32, there is a glaring flaw in your methodology.
Let's assume that int was 16 bit. You're assigning a value that will overflow z, so z itself is overflowed. When you calculate x+y you're also overflowing the int type, it's very likely that both cases will overflow to the same value, meaning you'd hit your equality regardless(this is probably compiler dependent, I'm not quite sure whether x+y will be promoted).
The correct way to do your experiment would be for z to have a larger data type than x and y. For example(Sorry for plain C, I'm not much of C# person. Hopefully it illustrated the methodology, however.)
int x = INT_MAX;
int y = INT_MAX;
int sum = x + y;
long long z = INT_MAX+INT_MAX;
if(sum == z)
printf("Why didn't sum overflow?!\n");
Comparing sum and z is important as comparing x+y and z may still come out fine depending on how the compiler handles promotion.
In C#, an Int is 4 bytes. So it maxes out at 2^31 or 2,147,483,648. If you want a 2 byte integer, use a short instead of an int.
Because an int in .NET is a signed 32 bit number with a range of -2,147,483,648 to 2,147,483,647.
Reference : http://msdn.microsoft.com/en-us/library/5kzh1b5w(VS.80).aspx
Because ints are 32-bit, holding values up to ±2GB.
An int's size is 4 byte so it can hold at least 2^31 which is around 2 billion.
The int keyword maps to the .NET Framework Int32 type, which can hold integers in the range from -2,147,483,648 to 2,147,483,647.
in C# int (System.Int32) is of 32 bits which can happily store this value.
you are given to print the result as "WTF?" .Then how should it display other value.
Int means int32 its range is –2147483648 to 2147483647
you are given the range of int16 :–32768 to 32767
This is the reason it is not throwing any error
First of all your code is in the range for int... However if it were not in the range then it wont complain either... coz you are never assigning a value back to any variable after doing X+Y in your if check...
Suppose if you were doing X * Y then it'll be calculated and the result would be a long value then the value from variable Z is taken and promoted to a long then both would be compared... Remember the casting from a lower range primitive to upper range primitive value is implicit.
int x = 200000; //In your code it was 20000
int y = 200000; //In your code it was 20000
int z = 40000;
// Why is it printing WTF? Isn't 40,000 > 32,767?
// Note: X + Y = 200000 and not < 32,767
// would pass compiler coz you are not assigning and values are compared as longs
// And since it's not equals to 40,000 the WTF did not got printed
if ((x + y) == z) Console.WriteLine("WTF?");
// And x * y >= z is true WTF MULTIPLY got printed
if ((x * y) >= z) Console.WriteLine("WTF MULTIPLY?");
// Compiler would fail since x can't hold 40,00,00,00,000
x = x * y;
All the above is true, however, it's important to know, that if you assign a number greater than 2^32, it will not compile!

Categories

Resources