|
Though math is also not my strong point, I would like to give it a shot.. Can you give two more "sample points" ?
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
Sure...
.25 = approx. 42Hz and .75 = approx. 189Hz
I've found a little more information. The displayed values on the end device are arranged into 101 steps so the mid value is actually 0.49 which displays 87Hz (this will be rounded though)
|
|
|
|
|
Are you sure that your given values (for .25, .5, .75) take into account that the range starts at 20Hz ? Because they all seem to be off by roughly 20 Hz here:
x a b f tgt xrev
-----------------------------------
0,00 10,00 1,00 20,0 20 0,00
0,25 7,75 0,89 62,1 42 0,25
0,50 5,50 0,74 118,7 89 0,50
0,75 3,25 0,51 205,5 189 0,75
1,00 1,00 0,00 400,0 400 1,00
x : input
a = 10 - x * 9
b = log(a)
f = 400 - b * 380
tgt : target
xrev = (10-10^((400-f)/380))/9
But maybe I'm missing something.
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
modified 17-Apr-15 20:03pm.
|
|
|
|
|
I've double checked the displayed results for those values and they are correct.
All the spec says is:
logf [20.000, 400.000, 101] Hz
which means: log float with a range of 20-400Hz, 101 valid steps
|
|
|
|
|
I'll give it another thought tomorrow. Maybe someone who's more talented in math will solve it in the meantime
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
Thanks for your help Sascha - I've got a solution, see my response to Kenneth below
|
|
|
|
|
DaveyM69 wrote: Thanks for your help Sascha Let's call it an attempt
Good to see you got a solution - I'll take a look at it myself, might come in handy some time.
cheers, Sascha
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
Frame the problem as a puzzle and drop it into the Lounge, I've seen a number of them get some detailed responses as long as they don't consider it a coding question you might get away with it
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Ha ha! I don't think I'd be that brave
Nearly there now thanks to Kenneth's find.
|
|
|
|
|
|
Brilliant find Kenneth!
I have tweaked the C# method on that page to:
float[] logValues = CreateLogValues(20, 400, 101);
public static float[] CreateLogValues(float minimum, float maximum, int valuesCount)
{
double logarithmicBase = Math.E;
double logMinimum = Math.Log(minimum);
double logMaximum = Math.Log(maximum);
double delta = (logMaximum - logMinimum) / (valuesCount - 1);
double accumulatedDelta = 0;
float[] values = new float[valuesCount];
for (int i = 0; i < valuesCount; ++i)
{
values[i] = (float)Math.Pow(logarithmicBase, logMinimum + accumulatedDelta);
accumulatedDelta += delta;
}
return values;
}
which is a good start. I should be able to sort the rest from here
Thanks
|
|
|
|
|
I have education in acoustics, were this comes up quite frequent
|
|
|
|
|
Ah, you should be careful though, LogE and Log10 gives you quite different results! And log10 is the one that is used in acoustics. I would know, I have a Masters degree in it
|
|
|
|
|
I'll keep my eye on it for other parameters that use the logf type. For the 20-400HZ one Math.E is giving the correct result.
Thanks for the heads up.
|
|
|
|
|
What I am trying to accomplish is that I am making the datatable to interpret large data. I only wanted to print out the header, then the data. Also only to show "Variable" and "Value" columns.
I'm not sure how to weed out the "Hex Value" column. Also to list the rows that are (Hidden = false).
I'm not sure how to accomplish this.
On the bottom code (with variable "res" does show all of the rows with all of the columns, but no header...
DataTable dataTable = new DataTable();
dataTable.Columns.Add("Variable", typeof(string));
dataTable.Columns.Add("Hex Value", typeof(Int64));
dataTable.Columns.Add("Value", typeof(string));
dataTable.Columns.Add("Hidden", typeof(bool));
dataTable.Rows.Add("Ronald", 0x0, "Value = 0", false);
dataTable.Rows.Add("Ronald", 0x1, "Value = 1", false);
dataTable.Rows.Add("Ronald", 0x2, "Value = 2", true);
dataTable.Rows.Add("Ronald", 0x4, "Value = 4", true);
dataTable.Rows.Add("Ronald", 0x8, "Value = 8", false);
dataTable.Rows.Add("Ronald", 0x16, "Value = 16", true);
dataTable.Rows.Add("Ronald", 0x32, "Value = 32", false);
dataTable.Rows.Add("Ronald", 0x64, "Value = 64", false);
dataTable.Rows.Add("Ronald", 0x128, "Value = 128", false);
dataTable.Rows.Add("Ronald", 0xFF, "Value = 255", true);
try
{
DataRow selectedRow = dataTable.Select("").FirstOrDefault(x => (Int64)x["Hex Value"] == Convert.ToInt64(tb_Input.Text, 16));
lbl_Result.Text = selectedRow["Value"].ToString();
}
catch
{
lbl_Result.Text = "Unknown";
}
string res = String.Join(Environment.NewLine, dataTable.Rows.OfType<DataRow>().Select(x => String.Join(" ; ", x.ItemArray)));
MessageBox.Show(res);
|
|
|
|
|
If dataTable is a System.Data.DataTable, then look into the DefaultView property.
|
|
|
|
|
I've got it...
Now one question hasn't been answered. How do I generate output showing only the "Variable" and "Value" columns?
|
|
|
|
|
Updated code... Seems to be working... Any suggestion for a better approach?
DataTable dataTable = new DataTable();
dataTable.Columns.Add("Variable", typeof(string));
dataTable.Columns.Add("Hex Value", typeof(Int64));
dataTable.Columns.Add("Value", typeof(string));
dataTable.Columns.Add("Hide", typeof(bool));
dataTable.Rows.Add("Ronald", 0x0, "Value = 0", false);
dataTable.Rows.Add("Ronald", 0x1, "Value = 1", true);
dataTable.Rows.Add("Ronald", 0x2, "Value = 2", false);
dataTable.Rows.Add("Ronald", 0x4, "Value = 4", true);
dataTable.Rows.Add("Ronald", 0x8, "Value = 8", false);
dataTable.Rows.Add("Ronald", 0x16, "Value = 16", false);
dataTable.Rows.Add("Ronald", 0x32, "Value = 32", false);
dataTable.Rows.Add("Ronald", 0x64, "Value = 64", true);
dataTable.Rows.Add("Ronald", 0x128, "Value = 128", false);
dataTable.Rows.Add("Ronald", 0xFF, "Value = 255", true);
try
{
DataRow selectedRow = dataTable.Select("").FirstOrDefault(x => (Int64)x["Hex Value"] == Convert.ToInt64(tb_Input.Text, 16));
lbl_Result.Text = selectedRow["Value"].ToString();
}
catch
{
lbl_Result.Text = "Unknown";
}
DataRow[] drArrRow = dataTable.Select("Hide = False");
DataTable filteredDataTable = new DataTable();
filteredDataTable.Columns.Add("Variable", typeof(string));
filteredDataTable.Columns.Add("Value", typeof(string));
foreach (DataRow dr in drArrRow)
{
filteredDataTable.Rows.Add(dr["Variable"], dr["Value"]);
}
string res = String.Join(Environment.NewLine, filteredDataTable.Rows.OfType<DataRow>().Select(x => String.Join(" ; ", x.ItemArray)));
MessageBox.Show(res);
|
|
|
|
|
Is the MessageBox the "final" way of displaying the values? Or is it just some temporary measure and should be replaced by something "nicer" eventually?
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
I plan to write the "res" value into text file (also Excel file.) I used this example as to see the quick result of the res value output through MessageBox before I start writing to the file.
|
|
|
|
|
I updated my answer, please take another look if you've seen an earlier version already.
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
Suggestions:
dataTable.Select(..) is meant to specify a filter-expression. If you don't specify one, it has basically the same effect as AsEnumerable()[^]. This would be the "cleaner" way in this case. (See code block below.)
Only resort to exception-catching if really neccessary. For the case that's there no matching "Hex Value" for the user-input, there's a way to do it without and you're already half-way there: FirstOrDefault(..) returns a default value if no matching value is found. If you don't use DefaultIfEmpty(..)[^] before FirstOrDefault(..) to specify a custom default-value, then the returned default-value is null* . So instead of catching the exception which will be thrown when accessing the null-valued selectedRow on the next line, just check if selectedRow is null.
* : for reference-types. (0 for value types)
If there can be only one matching value at most, use SingleOrDefault(..) instead of FirstOrDefault(..).
DataRow selectedRow = dataTable.AsEnumerable().SingleOrDefault(x => (Int64)x["Hex Value"] == Convert.ToInt64(tb_Input.Text, 16));
lbl_Result.Text = selectedRow != null ? selectedRow["Value"].ToString() : "Unknown";
If you want to write a "real" Excel-file (and not just a CSV-file) you will probably use some library for that. If that library accepts a DataTable as input, your approach from your reworked code (building a new DataTable with the desired content) is alright. A more generic approach would be the following (not neccessarily much better but I think you'll get some ideas from it):
var filtered = dataTable.AsEnumerable()
.Where(row => !(bool)row["Hide"])
.Select(row => new { variable = (string)row["Variable"], value = (string)row["Value"] });
StringBuilder sb = new StringBuilder();
sb.AppendLine("\"Variable\";\"Value\"");
foreach (var row in filtered)
{
sb.Append('"').Append(row.variable).Append('"');
sb.Append(';');
sb.Append('"').Append(row.value).Append('"');
sb.AppendLine();
}
string output = sb.ToString();
And a more compact version:
var filtered = dataTable.AsEnumerable()
.Where(row => !(bool)row["Hide"])
.Select(row => String.Concat("\"", row["Variable"], "\";\"", row["Value"], "\""));
StringBuilder sb = new StringBuilder();
sb.AppendLine("\"Variable\";\"Value\"");
sb.Append(String.Join(Environment.NewLine, filtered));
string output = sb.ToString();
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
modified 17-Apr-15 18:04pm.
|
|
|
|
|
Thanks! I'm learning more depth on the use of DataTable... I do appreciate some help with this. You've answered my questions.
|
|
|
|
|
You're welcome, glad I could help
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
I'm using .NET 4.0, and I want to make a delay that does not freeze my GUI. I tried:
Thread.sleep(1000);
but that freezes my GUI.
I also read that async can be used, but that was introduced until .net 4.5 and I'm using .net 4.0.
Can some one please tell me what to do?
Thanks.
|
|
|
|
|