After some research I have settled on ILNumerics for a Linear Algebra package in C#.
However I have having some issues working on ranges of the vector. I would like to modify the values in a Vector with a type of moving window, applying a function on the values in this window or range.
Any ideas on how to accomplish this? I cannot find how to do this in the documentation.
This is the kind of operation I would like to do:
ILArray<double> vec = ILMath.array(new [] {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0});
Console.WriteLine(vec);
// create a vector range from index 3-5
var range = vec[2, 5];
Console.WriteLine(range);
// modify all values in range
for (int i = 0; i < range.Length; i++)
range[i] += 10.0;
Console.WriteLine(range);
// view modified original vector
Console.WriteLine(vec);
This will not work, as the range incorrect and the vector cannot be written to using indexing.
Thanks.
I'm a bit unsure if I got this correctly. But you certainly can modify ILArray. Just make sure, you understand the basics for working with ILArray and how to handle the different array types. Especially, prevent from using var in conjunction with ILArray!
Read about the core array features:
http://ilnumerics.net/docs-core.html
Read how to create functions and handle the different ILNumerics array types:
http://ilnumerics.net/GeneralRules.html
I have modified your example. If this is not what you need, please comment on it:
ILArray<double> vec = ILMath.array(new[] { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 });
Console.WriteLine(vec);
// create a vector range from index 3-5
ILArray<int> range = array<int>(2,3,4,5);
Console.WriteLine(range);
// modify all values in range
for (int i = 0; i < 3; i++) // make tree steps. Modify as needed!
vec[range + i] = vec[range + i] + i;
Console.WriteLine(range);
// view modified original vector
Console.WriteLine(vec);
#Edit: From the comments... this may bring us closer to what you are trying to achieve?
for (int i = 0; i < 3; i++) // make tree steps. Modify as needed!
// dynamic subarrays using ILMath.r()
vec[r(i,i+5)] = vec[r(i,i+5)] + ... ;
Note that you have to use ILMath.r(..) instead of r(..) if your code is not defined in a class which derives from ILMath. Note further that subarray range definitions with r() can be combined with string definitions arbitrarly. This could help to translate it to cases, where matrices or n-dim arrays are involved.
Related
I'm trying to calculate the +DI and -DI values (period 28) using the TA-lib library. The values I am getting are not similar to the values on my charting platform. Please find my code below and let me know if I'm missing anything. Also, the ADX value returned from the TA-lib is also wrong. Thanks.
Below, you'll find the code to calculate the +DI using the TA-lib library. The value returned by the library is far from the value I see on my charting platform. The only inputs are highPrices, lowPrices and closePrices. These are arrays contains the high, low and closing prices. The values in these arrays match the values on my charting platform and yet the value returned is wrong.
Thanks for your time.
double[] output = new double[closePrices.Length];
int begin;
int length;
Core.RetCode retCode = Core.PlusDI(closePrices.Length - 1, closePrices.Length - 1, highPrices, lowPrices, closePrices, period, out begin, out length, output);
if (retCode == Core.RetCode.Success)
{
for (int i = 0; i < length; i++)
{
result = Math.Round(output[i], 5);
}
}
return result;
This is my idea to program a simple math module (function) that can be called from another main program. It calculates the FWHM(full width at half the max) of a curve. Since this is my first try at Visual Studio and C#. I would like to know few basic programming structures I should learn in C# coming from a Mathematica background.
Is double fwhm(double[] data, int c) indicate the input arguments
to this function fwhm should be a double data array and an Integer
value? Did I get this right?
I find it difficult to express complex mathematical equations (line 32/33) to express them in parenthesis and divide one by another, whats the right method to do that?
How can I perform Mathematical functions on elements of an Array like division and store the results in the same Array?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DEV_2
{
class fwhm
{
static double fwhm(double[] data, int c) // data as 2d data and c is integer
{
double[] datax;
double[] datay;
int L;
int Mag = 4;
double PP = 2.2;
int CI;
int k;
double Interp;
double Tlead;
double Ttrail;
double fwhm;
L = datay.Length;
// Create datax as index for the number of elemts in data from 1-Length(data).
for (int i = 1; i <= data.Length; i++)
{
datax[i] = (i + 1);
}
//Find max in datay and divide all elements by maxValue.
var m = datay.Length; // Find length of datay
Array.ForEach(datay, (x) => {datay[m++] = x / datay.Max();}); // Divide all elements of datay by max(datay)
double maxValue = datay.Max();
CI = datay.ToList().IndexOf(maxValue); // Push that index to CI
// Start to search lead
int k = 2;
while (Math.Sign(datay[k]) == Math.Sign(datay[k-1]-0.5))
{
k=k+1;
}
Interp = (0.5-datay[k-1])/(datay[k]-datay[k-1]);
Tlead = datax[k-1]+Interp*(datax[k]-datax[k-1]);
CI = CI+1;
// Start search for the trail
while (Math.Sign(datay[k]-0.5) == Math.Sign(datay[k-1]-0.5) && (k<=L-1))
{
k=k+1;
}
if (k != L)
{
Interp = (0.5-datay[k-1])/(datay[k]-datay[k-1]);
Ttrail = datax[k-1] + Interp*(datax[k]-datax[k-1]);
fwhm =((Ttrail-Tlead)*PP)/Mag;
}
}//end main
}//end class
}//end namespace
There are plenty of pitfalls in C#, but working through problems is a great way to find and learn them!
Yes, when passing parameters to a method the correct syntax is MethodName(varType varName) seperated by a comma for multiple parameters. Some pitfalls arise here with differences in passing Value types and Reference types. If you're interested here is some reading on the subject.
Edit: As pointed out in the comments you should write code as best as possible to require as few comments as possible (thus paragraph between #3 and #4), however if you need to do very specific and slightly complex math then you should comment to clarify what is occuring.
If you mean difficulties understanding, make sure you comment your code properly. If you mean difficulties writing it, you can create variables to simplify reading your code (but generally unnecessary) or look up functions or libraries to help you, this is a bit open ended question if you have a particular functionality you are looking for perhaps we could be of more help.
You can access your array via indexes such as array[i] will get the ith index. Following this you can manipulate the data that said index is pointing to in any way you wish, array[i] = (array[i]/24)^3 or array[i] = doMath(array[i])
A couple things you can do if you like to clean a little, but they are preference based, is not declare int CI; int k; in your code before you initialize them with int k = 2;, there is no need (although you can if it helps you). The other thing is to correctly name your variables, common practice is a more descriptive camelCase naming, so perhaps instead of int CI = datay.ToList().IndexOf(maxValue); you coud use int indexMaxValueYData = datay.ToList().IndexOf(maxValue);
As per your comment question "What would this method return?" The method will return a double, as declared above. returnType methodName(parameters) However you need to add that in your code, as of now I see no return line. Such as return doubleVar; where doubleVar is a variable of type double.
I'm trying to convert a c# code into a matlab code. So in c# code I have a linklist where x,y coordinates are inserted. I'm using "Array.Resize(ref arr, 1);" to insert x,y value. So whenever I insert values old value goes to the bottom of the array. I'm also using resize method to shrink(or break) the array from certain indexes. How can I recreate this in matlab. I read about reshape method in matlab but I don't understand how to apply it. dlnode method in matlab only can take one value at a time.
Point[] arr = new Point[8];
for (int x= 0; x < arr.Length; x++)
{
Array.Resize<Point>(ref arr, 1);
arr[x].X = x; (x,y values will get from text boxes)
arr[x].Y= y;
}
Any help would be highly appreciated.
Is this what you want to do?
A = [x y]
B = [A ; B]
And by opposite:
A = B(:,1)
B = B(:,2:end)
I am unable to assign dynamic value to an array which is double. If i keep it static, I am able to do it. Help me out.
I have defined a array as double whose size could be dynamic. Then I calculated some value and want to assign that value to this double array.
I did..
double[] entropy_db_col;
But I am getting an error. array out of index.
If i calculate, (double)entropy_db - (double)a, I am getting a static value.
Even if I do entropy_db_col[0] = (double)entropy_db - (double)a;, then also I am getting the error? What should I do ?
Then I want to find the largest value from this array? Is this code right ?
largest = Convert.ToInt32(entropy_db_col[0].ToString());
Please help me out.
It would be great.
I solved this, but now the problem I get is :
I get entropy_db_col[0] value, then..when I iterate and get entropy_db_col[1] value, the value of entropy_db_col[0] becomes 0. Similarly when I get entropy_db_col[2], the value of entropy_db_col[1] and entropy_db_col[0] becomes 0..what should i do ?
create memory with data.count
before it used
entropy_db_col=new double[data.count]
Dynamic array
A double[] is not a dynamic array so much as an array of undefined size. It must first be defined with a concrete size, such as new double[data.Count] before it can be used, but this causes its size to be fixed.
If you want an array that can change size at any time, use a List<double> instead from the System.Collections.Generic namespace.
using System.Collections.Generic;
...
List<double> entropy_db_col = new List<double>();
for (int i = 0; i < data.Count; i++)
{
\\some calculation
entropy_db_col.Add((double)entropy_db - (double)a);
}
Largest value
To find the largest value in .Net 3.5 or later, you can use:
using System.Linq;
...
double largest = entropy_db_col.Max();
Or if you're using an version of .Net older than 3.5, you can use:
double largest = entropy_db_col[0];
for (int j = 1; j < entropy_db_col.Length; j++)
{
if (largest < entropy_db_col[j])
{
largest = entropy_db_col[j];
}
}
I'm trying to implement a discrete fourier transform, but it's not working. I'm probably have written a bug somewhere, but I haven't found it yet.
Based on the following formula:
This function does the first loop, looping over X0 - Xn-1...
public Complex[] Transform(Complex[] data, bool reverse)
{
var transformed = new Complex[data.Length];
for(var i = 0; i < data.Length; i++)
{
//I create a method to calculate a single value
transformed[i] = TransformSingle(i, data, reverse);
}
return transformed;
}
And the actual calculating, this is probably where the bug is.
private Complex TransformSingle(int k, Complex[] data, bool reverse)
{
var sign = reverse ? 1.0: -1.0;
var transformed = Complex.Zero;
var argument = sign*2.0*Math.PI*k/data.Length;
for(var i = 0; i < data.Length; i++)
{
transformed += data[i]*Complex.FromPolarCoordinates(1, argument*i);
}
return transformed;
}
Next the explaination of the rest of the code:
var sign = reverse ? 1.0: -1.0; The reversed DFT will not have -1 in the argument, while a regular DFT does have a -1 in the argument.
var argument = sign*2.0*Math.PI*k/data.Length; is the argument of the algorithm. This part:
then the last part
transformed += data[i]*Complex.FromPolarCoordinates(1, argument*i);
I think I carefully copied the algorithm, so I don't see where I made the mistake...
Additional information
As Adam Gritt has shown in his answer, there is a nice implementation of this algorithm by AForge.net. I can probably solve this problem in 30 seconds by just copying their code. However, I still don't know what I have done wrong in my implementation.
I'm really curious where my flaw is, and what I have interpreted wrong.
My days of doing complex mathematics are a ways behind me right now so I may be missing something myself. However, it appears to me that you are doing the following line:
transformed += data[i]*Complex.FromPolarCoordinates(1, argument*i);
when it should probably be more like:
transformed += data[i]*Math.Pow(Math.E, Complex.FromPolarCoordinates(1, argument*i));
Unless you have this wrapped up into the method FromPolarCoordinates()
UPDATE:
I found the following bit of code in the AForge.NET Framework library and it shows additional Cos/Sin operations being done that are not being handled in your code. This code can be found in full context in the Sources\Math\FourierTransform.cs: DFT method.
for ( int i = 0; i < n; i++ )
{
dst[i] = Complex.Zero;
arg = - (int) direction * 2.0 * System.Math.PI * (double) i / (double) n;
// sum source elements
for ( int j = 0; j < n; j++ )
{
cos = System.Math.Cos( j * arg );
sin = System.Math.Sin( j * arg );
dst[i].Re += ( data[j].Re * cos - data[j].Im * sin );
dst[i].Im += ( data[j].Re * sin + data[j].Im * cos );
}
}
It is using a custom Complex class (as it was pre-4.0). Most of the math is similar to what you have implemented but the inner iteration is doing additional mathematical operations on the Real and Imaginary portions.
FURTHER UPDATE:
After some implementation and testing I found that the code above and the code provided in the question produce the same results. I also found, based on the comments what the difference is between what is generated from this code and what is produced by WolframAlpha. The difference in the results is that it would appear that Wolfram is applying a normalization of 1/sqrt(N) to the results. In the Wolfram Link provided if each value is multiplied by Sqrt(2) then the values are the same as those generated by the above code (rounding errors aside). I tested this by passing 3, 4, and 5 values into Wolfram and found that my results were different by Sqrt(3), Sqrt(4) and Sqrt(5) respectfully. Based on the Discrete Fourier Transform information provided by wikipedia it does mention a normalization to make the transforms for DFT and IDFT unitary. This might be the avenue that you need to look down to either modify your code or understand what Wolfram may be doing.
Your code is actually almost right (you are missing an 1/N on the inverse transform). The thing is, the formula you used is typically used for computations because it's lighter, but on purely theorical environments (and in Wolfram), you would use a normalization by 1/sqrt(N) to make the transforms unitary.
i.e. your formulas would be:
Xk = 1/sqrt(N) * sum(x[n] * exp(-i*2*pi/N * k*n))
x[n] = 1/sqrt(N) * sum(Xk * exp(i*2*pi/N * k*n))
It's just a matter of convention in normalisation, only amplitudes change so your results weren't that bad (if you hadn't forgotten the 1/N in the reverse transform).
Cheers