I have some MATLAB code that filters an input signal using filter:
CUTOFF = 0.05;
FS = 5000;
[b, a] = butter(1, CUTOFF / (FS / 2), 'high');
% b = [0.99996859, -0.99996859]
% a = [1.0, -0.99993717]
dataAfter = filter(b, a, dataBefore);
I'm trying to convert this code to C#. I have already got the butter function to work pretty fast, but now I'm stuck converting the filter function.
I have read the MATLAB filter documentation and Python Scipy.signal filter documentation, but there is a term present in the transfer function definition that I don't understand.
Here is the "rational transfer function" definition from the linked documentation:
b[0] + b[1]z^(-1) + ... + b[M]z^(-M)
Y(z) = _______________________________________ X(z)
a[0] + a[1]z^(-1) + ... + a[N]z^(-N)
Correct me if i'm wrong, but z is the current element of input data, and Y(z) is the output?
If the above this is true, what is X(z) in this equation?
I want to understand this to implement it in C#, if there is an equivalent option then please enlighten me.
In the More About section of the matlab docs as you pointed out, they describe:
The input-output description of the filter operation on a vector in the Z-transform domain is a rational transfer function. A rational transfer function is of the form,
b[0] + b[1]z^(-1) + ... + b[M]z^(-M)
Y(z) = _______________________________________ X(z)
a[0] + a[1]z^(-1) + ... + a[N]z^(-N)
Rearranging:
Y(z) b[0] + b[1]z^(-1) + ... + b[M]z^(-M)
H(z) = ____ = _______________________________________
X(z) a[0] + a[1]z^(-1) + ... + a[N]z^(-N)
Thus, X(z) is the z-domain transform of the input vector x (seeDigital Filter). It is important to mention that, also in the docs they give an alternate representation of the transfer function as a difference equation
Which lends itself better to be ported into code. One possible implementation in C#, could be (using this answer as reference)
public static double[] Filter(double[] b, double[] a, double[] x)
{
// normalize if a[0] != 1.0. TODO: check if a[0] == 0
if(a[0] != 1.0)
{
a = a.Select(el => el / a[0]).ToArray();
b = b.Select(el => el / a[0]).ToArray();
}
double[] result = new double[x.Length];
result[0] = b[0] * x[0];
for (int i = 1; i < x.Length; i++)
{
result[i] = 0.0;
int j = 0;
if ((i < b.Length) && (j < x.Length))
{
result[i] += (b[i] * x[j]);
}
while(++j <= i)
{
int k = i - j;
if ((k < b.Length) && (j < x.Length))
{
result[i] += b[k] * x[j];
}
if ((k < x.Length) && (j < a.Length))
{
result[i] -= a[j] * result[k];
}
}
}
return result;
}
Driver:
static void Main(string[] args)
{
double[] dataBefore = { 1, 2, 3, 4 };
double[] b = { 0.99996859, -0.99996859 };
double[] a = { 1.0, -0.99993717 };
var dataAfter = Filter(b1, a, dataBefore);
}
Output
Matlab dataAfter = [0.99996859 1.999874351973491 2.999717289867956 3.999497407630634]
CSharp dataAfter = [0.99996859 1.9998743519734905 2.9997172898679563 3.999497407630634]
UPDATE
If the coefficient vectors a and b have a fixed length of 2 the filtering function can be simplified to:
public static double[] Filter(double[] b, double[] a, double[] x)
{
// normalize if a[0] != 1.0. TODO: check if a[0] == 0
if (a[0] != 1.0)
{
a = a.Select(el => el / a[0]).ToArray();
b = b.Select(el => el / a[0]).ToArray();
}
int length = x.Length;
double z = 0.0;
double[] y = new double[length]; // output filtered signal
double b0 = b[0];
double b1 = b[1];
double a1 = a[1];
for (int i = 0; i < length; i++)
{
y[i] = b0 * x[i] + z;
z = b1 * x[i] - a1 * y[i];
}
return y;
}
I have problem with the calculation of the median when I put 1,2, 3 my median is = 44 i don't know why
double wynik = 0;
string x1 = textBox1.Text;
string[] tab = x1.Split(',');
int n = tab.Length;
Array.Sort(tab);
if (n % 2 == 0)
{
double c = x1[(n / 2) -1];
double v = x1[(n / 2)];
wynik = (c + v) / 2;
}
else
wynik = x1[n / 2];
textBox2.Text = wynik.ToString();
That is because 44 is the ASCII value of ,. And in your string, using your current method now, the median is the comma character , value = 44
To get the median, consider of splitting the string by , and then convert each value to numeric data (like int) and then sort it and simply get the middle value among the sorted data..
double wynik = 0;
string x1 = textBox1.Text;
int[] tab = x1.Split(',').Select(x => Convert.ToInt32(x)).ToArray(); //this is the trick
int n = tab.Length;
Array.Sort(tab);
int median = tab[n/2]; //here is your median
Your problem is that you are calculating with characters instead of number.
So let's say your textBox1.Text is "1,2,3". Then x1[(n/2)-1] would point at the character '1', which has the double value of 48 or something.
You need to parse the strings into int using int.Parse:
int[] tab = x1.Split(',').Select(s => int.Parse(s)).ToArray();
And then use these values instead the string again:
if (n % 2 == 0)
{
double c = tab[(n / 2) -1]; // tab instead of x1!
double v = tab[(n / 2)]; // tab instead of x1!
wynik = (c + v) / 2;
}
else
wynik = tab[n / 2]; // tab instead of x1
static void Main(string[] args)
{
Console.WriteLine("Define Array Size");
int size = Convert.ToInt32(Console.ReadLine());
float reference = 0;
int[] newArray = new int[size];
for (int i = 0; i < newArray.Length; i++)
{
newArray[i] = Convert.ToInt32(Console.ReadLine());
reference = reference + newArray[i];
}
float Median = reference / newArray.Length;
Console.WriteLine("The Median is ="+Median);
}
I'm trying to randomly generate blocks on a flat map and make it so that they don't overlap each other.
I have made a matrix (c# array) of the size of the map (500x500), the blocks have a scale between 1 and 5.
The code works but if a generated block overlaps another one, it is destroyed and not regenerated somewhere else.
Only around 80 of the 1000 blocks I try to generate don't overlap another block.
Here is a picture of the map with around 80 blocks generated, the green squares are blocks
void generateElement(int ratio, int minScale, int maxScale, GameObject g) {
bool elementFound = false;
for (int i = 0; i < ratio * generationDefault; i++) {
GameObject el;
// Randomly generate block size and position
int size = Random.Range(minScale, maxScale + 1);
int x = Random.Range(0, mapSizex + 1 - size);
int y = Random.Range(0, mapSizey + 1 - size);
// Check if there is already an element
for (int j = x; j < x + size; j++)
for (int k = y; k < y + size; k++)
if (map[j][k] != null)
elementFound = true;
if (elementFound)
continue;
else {
el = (GameObject)Instantiate(g, new Vector3(x + (float)size / 2, (float)size / 2, y + (float)size / 2), Quaternion.Euler(0, 0, 0));
el.transform.localScale *= size;
}
// Create element on map array
for (int j = x; j < x + size; j++)
for (int k = y; k < y + size; k++)
if (map[j][k] == null) {
map[j][k] = el.GetComponent<ObjectInterface>();
}
}
}
I thought of 3 possible fixes
I should set the size of the block depending of the place it has.
I should use another randomization algorithm.
I'm not doing this right.
What do you think is the best idea ?
UPDATE
I got the code working much better. I now try to instantiate the blocks multiple times if needed (maximum 5 for the moment) and I fixed the bugs. If there are already many elements on the map, they will not always be instantiated and that's what I wanted, I just have to find the right amount of times it will try to instantiate the block.
I tried instantiating 1280 elements on a 500x500 map. It takes only about 1.5 second and it instantiated 1278/1280 blocks (99.843%).
void generateElement(int ratio, int minScale, int maxScale, GameObject g) {
bool elementFound = false;
int cnt = 0;
// Generate every block
for (int i = 0; i < ratio * generationDefault; i++) {
GameObject el = null;
// Randomly generate block size and position
int size, x, y, tryCnt = 0;
// Try maximum 5 times to generate the block
do {
elementFound = false;
// Randomly set block size and position
size = Random.Range(minScale, maxScale + 1);
x = Random.Range(0, mapSizex + 1 - size);
y = Random.Range(0, mapSizey + 1 - size);
// Check if there is already an element
for (int j = x; j < x + size; j++)
for (int k = y; k < y + size; k++)
if (map[j][k] != null)
elementFound = true;
tryCnt++;
} while (elementFound && tryCnt < 5);
if (tryCnt >= 5 && elementFound) continue;
// Instantiate the block
el = (GameObject)Instantiate(g, new Vector3(x + (float)size / 2, (float)size / 2, y + (float)size / 2), Quaternion.Euler(0, 0, 0));
el.transform.localScale *= size;
// Create element on map array
for (int j = x; j < x + size; j++)
for (int k = y; k < y + size; k++)
if (map[j][k] == null) {
map[j][k] = el.GetComponent<ObjectInterface>();
}
cnt++;
}
print("Instantiated " + cnt + "/" + ratio * generationDefault);
}
This is incredibly difficult to do well.
Here's a quick solution you'll maybe like ... depending on your scene.
actualWidth = 500 //or whatever. assume here is square
// your blocks are up to 5 size
chunkWidth = actualWidth / 5
// it goes without saying, everything here is an int
kChunks = chunkWidth*chunkWidth
List<int> shuf = Enumerable.Range(1,kChunks).OrderBy(r=>Random.value).ToList();
howManyWanted = 1000
shuf = shuf.Take(howManyWanted)
foreach( i in shuf )
x = i % actualWidth
y = i / actualWidth
make block at x y
put block in list allBlocks
HOWEVER ............
...... you'll see that this looks kind of "regular", so do this:
Just randomly perturb all the blocks. Remember, video game programming is about clever tricks!
Ideally, you have to start from the middle and work your way out; in any event you can't just do them in a line. Shuffling is OK. So, do this ..
harmonic = 3 //for example. TRY DIFFERENT VALUES
function rh = Random.Range(1,harmonic) (that's 1 not 0)
function rhPosNeg
n = rh
n = either +n or -n
return n
function onePerturbation
{
allBlocks = allBlocks.OrderBy(r => Random.value) //essential
foreach b in allBlocks
newPotentialPosition = Vector2(rhPosNeg,rhPosNeg)
possible = your function to check if it is possible
to have a block at newPotentialPosition,
however be careful not to check "yourself"
if possible, move block to newPotentialPosition
}
The simplest approach is just run onePerturbation, say, three times. Have a look at it between each run. Also try different values of the harmonic tuning factor.
There are many ways to perturb fields of differently-sized blocks, above is a KISS solution that hopefully looks good for your situation.
Coding note...
How to get sets of unique random numbers.
Just to explain this line of code...
List<int> shuf = Enumerable.Range(1,kChunks).OrderBy(r=>Random.value).ToList();
If you are new to coding: say you want to do this: "get a hundred random numbers, from 1 to million, but with no repeats".
Fortunately, this is a very well known problem with a very simple solution.
The way you get numbers with no repeats, is simply shuffle all the numbers, and then take how many you want off the top.
For example, say you need a random couple of numbers from 1-10 but with no repeats.
So, here's the numbers 1-10 shuffled: 3,8,6,1,2,7,10,9,4,5
Simply take what you need off the front: so, 3, 8, 6 etc.
So to make an example let's say you want twelve numbers, no repeats, from 1 through 75. So the first problem is, you want a List with all the numbers up to 75, but shuffled. In fact you do that like this ..
List<int> shuf = Enumerable.Range(1,75).OrderBy(r=>Random.value).ToList();
So that list is 75 items long. You can check it by saying foreach(int r in shuf) Debug.Log(r);. Next in the example you only want 12 of those numbers. Fortunately there's a List call that does this:
shuf = shuf.Take(12)
So, that's it - you now have 12 numbers, no repeats, all random between 1 and 75. Again you can check with foreach(int r in shuf) Debug.Log(r);
In short, when you want "n" numbers, no repeats, between 1 and Max, all you have to so is this:
List<int> shuf = Enumerable.Range(1,Max).OrderBy(r=>Random.value).ToList();
shuf = shuf.Take(n);
et voilĂ , you can check the result with foreach(int r in shuf) Debug.Log(r);
I just explain this at length because the question is often asked "how to get random numbers that are unique". This is an "age-old" programming trick and the answer is simply that you shuffle an array of all the integers involved.
Interestingly, if you google this question ("how to get random numbers that are unique") it's one of those rare occasions where google is not much help, because: whenever this question is asked, you get a plethora of keen new programmers (who have not heard the simple trick to do it properly!!) writing out huge long complicated ideas, leading to further confusion and complication.
So that's how you make random numbers with no repeats, fortunately it is trivial.
if (elementFound) continue; will skip out this current loop iteration. You need to wrap the int x=Random..; int y=Random()..; part in a while loop with the condition being while(/* position x/y already occupued*/) { /* generate new valid point */} like this for example:
void generateElement(int ratio, int minScale, int maxScale, GameObject g) {
for (int i = 0; i < ratio * generationDefault; i++) {
GameObject el;
// Randomly generate block size and position
bool elementFound = false;
int size, x, y;
do
{
elementFound = false;
size = Random.Range(minScale, maxScale + 1);
x = Random.Range(0, mapSizex + 1 - size);
y = Random.Range(0, mapSizey + 1 - size);
// Check if there is already an element
for (int j = x; j < x + size; j++)
for (int k = y; k < y + size; k++)
if (map[j][k] != null)
elementFound = true;
} while(elementFound);
el = (GameObject)Instantiate(g, new Vector3(x + (float)size / 2, (float)size / 2, y + (float)size / 2), Quaternion.Euler(0, 0, 0));
el.transform.localScale *= size;
// Create element on map array
for (int j = x; j < x + size; j++)
for (int k = y; k < y + size; k++)
if (map[j][k] == null) {
map[j][k] = el.GetComponent<ObjectInterface>();
}
}
}
You shouldn't be getting that many collisions.
Assuming your blocks were ALL 5 units wide and you're trying to fit them into a grid of 500,500 you would have 100*100 spaces for them at minimum, which gives 10,000 spaces into which to fit 1,000 blocks.
Try playing around with this code:
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
var result = PlaceNonOverlappingBlocks(1000, 5, 500, 500);
}
static List<Block> PlaceNonOverlappingBlocks(int count, int maxBlockSize, int mapX, int mapY)
{
var map = new bool[mapY, mapX];
var rng = new Random();
var result = new List<Block>(count);
int collisions = 0;
while (count > 0)
{
int size = rng.Next(1, maxBlockSize + 1);
int x = rng.Next(0, mapX - size);
int y = rng.Next(0, mapY - size);
if (fits(map, x, y, size))
{
result.Add(new Block(x, y, size));
addToMap(map, x, y, size);
--count;
}
else
{
if (++collisions> 100000)
throw new InvalidOperationException("Hell has frozen over");
}
}
// This is just for diagnostics, and can be removed.
Console.WriteLine($"There were {collisions} collisions.");
return result;
}
static void addToMap(bool[,] map, int px, int py, int size)
{
for (int x = px; x < px+size; ++x)
for (int y = py; y < py + size; ++y)
map[y, x] = true;
}
static bool fits(bool[,] map, int px, int py, int size)
{
for (int x = px; x < px + size; ++x)
for (int y = py; y < py + size; ++y)
if (map[y, x])
return false;
return true;
}
internal class Block
{
public int X { get; }
public int Y { get; }
public int Size { get; }
public Block(int x, int y, int size)
{
X = x;
Y = y;
Size = size;
}
}
}
}
how to find the min and max for quadratic equation using c# ??
f(x,y) = x^2 + y^2 + 25 * (sin(x)^2 + sin(y)^2) ,where (x,y) from (-2Pi, 2Pi) ??
in the manual solving I got min is = 0 , max = 8Pi^2 = 78.957 .
I tried to write the code based on liner quadratic code but something goes totally wrong
this code give the min = -4.?? and the max = 96 could you help to know where is my mistake please ??
I uploaded the code to dropbox if anyone can have look : https://www.dropbox.com/s/p7y6krk2gk29i9e/Program.cs
double[] X, Y, Result; // Range array and result array.
private void BtnRun_Click(object sender, EventArgs e)
{
//Set any Range for the function
X = setRange(-2 * Math.PI, 2 * Math.PI, 10000);
Y = setRange(-2 * Math.PI, 2 * Math.PI, 10000);
Result = getOutput_twoVariablesFunction(X, Y);
int MaxIndex = getMaxIndex(Result);
int MinIndex = getMinIndex(Result);
TxtMin.Text = Result[MinIndex].ToString();
TxtMax.Text = Result[MaxIndex].ToString();
}
private double twoVariablesFunction(double x,double y)
{
double f;
//Set any two variables function
f = Math.Pow(x, 2) + Math.Pow(y, 2) + 25 * (Math.Pow(Math.Sin(x), 2) + Math.Pow(Math.Sin(y), 2));
return f;
}
private double[] setRange(double Start, double End, int Sample)
{
double Step = (End - Start) / Sample;
double CurrentVaue = Start;
double[] Array = new double[Sample];
for (int Index = 0; Index < Sample; Index++)
{
Array[Index] = CurrentVaue;
CurrentVaue += Step;
}
return Array;
}
private double[] getOutput_twoVariablesFunction(double[] X, double[] Y)
{
int Step = X.Length;
double[] Array = new double[Step];
for (int Index = 0; Index < X.Length ; Index++)
{
Array[Index] = twoVariablesFunction(X[Index], Y[Index]);
}
return Array;
}
private int getMaxIndex(double[] ValuesArray)
{
double M = ValuesArray.Max();
int Index = ValuesArray.ToList().IndexOf(M);
return Index;
}
private int getMinIndex(double[] ValuesArray)
{
double M = ValuesArray.Min();
int Index = ValuesArray.ToList().IndexOf(M);
return Index;
}
Do you want to compute (sin(x))^2 or sin(x^2)? In your f(x,y) formula it looks like (sin(x))^2, but in your method twoVariablesFunction like sin(x^2).
int DiferentPixels = 0;
Bitmap first = new Bitmap("First.jpg");
Bitmap second = new Bitmap("Second.jpg");
Bitmap container = new Bitmap(first.Width, first.Height);
for (int i = 0; i < first.Width; i++)
{
for (int j = 0; j < first.Height; j++)
{
int r1 = second.GetPixel(i, j).R;
int g1 = second.GetPixel(i, j).G;
int b1 = second.GetPixel(i, j).B;
int r2 = first.GetPixel(i, j).R;
int g2 = first.GetPixel(i, j).G;
int b2 = first.GetPixel(i, j).B;
if (r1 != r2 && g1 != g2 && b1 != b2)
{
DiferentPixels++;
container.SetPixel(i, j, Color.Red);
}
else
container.SetPixel(i, j, first.GetPixel(i, j));
}
}
int TotalPixels = first.Width * first.Height;
float dierence = (float)((float)DiferentPixels / (float)TotalPixels);
float percentage = dierence * 100;
With this portion of Code im comparing 2 Images foreach Pixels and yes it work's it return's Percentage of difference ,so it compares each Pixel of First Image with pixel in same index of Second Image .But what is wrong here ,i have a huge precision maybe it should not work like that ,the comparison ,and maybe there are some better algorithms which are faster and more flexible .
So anyone has an idea how can i transform the comparison ,should i continue with that or should i compare Colors of Each Pixels or ....
PS : If anyone has a solution how to make Parallel this code ,i would also accept it ! Like expanding this to 4 Threads would they do it faster right in a Quad Core?
One obvious change would be call GetPixel only once per Bitmap, and then work with the returned Color structs directly:
for (int i = 0; i < first.Width; ++i)
{
for (int j = 0; j < first.Height; ++j)
{
Color secondColor = second.GetPixel(i, j);
Color firstColor = first.GetPixel(i, j);
if (firstColor != secondColor)
{
DiferentPixels++;
container.SetPixel(i, j, Color.Red);
}
else
{
container.SetPixel(i, j, firstColor);
}
}
}
For speed, resize the images to something very small (16x12, for example) and do the pixel comparison. If it is a near match, then try it at higher resolution.