-
Notifications
You must be signed in to change notification settings - Fork 100
Does np.interp Implemented? #132
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
It is not implemented yet and if you look closely you will notice that the code in the test case (which is auto-generated by the way) everything is commented out using I am looking into it if this can be implemented easily. |
Got it,I've use DeepSeek to trying implement this,hope it works as expected. Temp Close. |
Can you share your solution please? |
using System;
using System.Collections.Generic;
using System.Text;
namespace ShtolaUtils
{
/// <summary>
/// 用于模拟Numpy.interp的1D线性插值类
/// </summary>
public class Interpolator
{
/// <summary>
/// 用于模拟Numpy.interp的1D线性插值
/// </summary>
/// <param name="x">用于计算插值值的x坐标。</param>
/// <param name="xp">X轴上的数据点。<br></br>
/// 当周期为true时则必定要求为单调递增,反之XP将在标准化后进行内部排序(用不上period)</param>
/// <param name="fp">Y轴上的数据点,和XP同长</param>
/// <param name="left">FP的左极值点</param>
/// <param name="right">FP的右极值点</param>
/// <returns>插值后的1D Array</returns>
/// <exception cref="ArgumentException"></exception>
public static double[] Interp(double[] x, double[] xp, double[] fp, double left = double.NaN, double right = double.NaN)
{
// 参数校验
if (xp.Length != fp.Length)
throw new ArgumentException("xp和fp长度必须一致");
if (x.Length == 0)
return new double[0];
// 处理边界默认值
if (double.IsNaN(left)) left = fp[0];
if (double.IsNaN(right)) right = fp[^1]; // 使用 ^1 表示最后一个元素
// 缓存边界值
double minXP = xp[0];
double maxXP = xp[^1];
double[] result = new double[x.Length];
int xpIndex = 0;
for (int i = 0; i < x.Length; i++)
{
double currentX = x[i];
// 处理左边界
if (currentX <= minXP)
{
result[i] = left;
continue;
}
// 处理右边界
if (currentX >= maxXP)
{
result[i] = right;
continue;
}
// 找到当前 x 在 xp 中的位置
while (xpIndex < xp.Length - 1 && xp[xpIndex + 1] < currentX)
{
xpIndex++;
}
// 计算线性插值
double x0 = xp[xpIndex];
double x1 = xp[xpIndex + 1];
double y0 = fp[xpIndex];
double y1 = fp[xpIndex + 1];
// 提前计算斜率
double slope = (y1 - y0) / (x1 - x0);
result[i] = y0 + slope * (currentX - x0);
}
return result;
}
}
} Not testing so much with performance,but i got same result as original numpy implementation |
Ok, I see. Of course numpy will be faster if the arrays are really big. If they are small your c# code may be faster than Numpy because there is an overhead of calling into python. Anyway, I'll put this on my todo list and let you know when it's done. |
Thanks a lot buddy,hope everything in progress and peachy |
Hi bud,is that everything going as progressed or not?Is that feature published? |
I got it working. The following testcase shows the usage: [TestMethod]
public void interpTest()
{
// >>> xp = [1, 2, 3]
// >>> fp = [3, 2, 0]
// >>> np.interp(2.5, xp, fp)
// 1.0
// >>> np.interp([0, 1, 1.5, 2.72, 3.14], xp, fp)
// array([ 3. , 3. , 2.5 , 0.56, 0. ])
// >>> UNDEF = -99.0
// >>> np.interp(3.14, xp, fp, right=UNDEF)
// -99.0
//
var xp = new float[] { 1, 2, 3 };
var fp = new float[] { 3, 2, 0 };
Assert.AreEqual(1.0f, np.interp(2.5f, xp, fp));
var given = np.interp(new float[] { 0, 1, 1.5f, 2.72f, 3.14f }, xp, fp);
var expected =
"array([3. , 3. , 2.5 , 0.55999994, 0. ])";
Assert.AreEqual(expected, given.repr);
var UNDEF = -99.0f;
Assert.AreEqual(-99.0f, np.interp(3.14f, xp, fp, right: UNDEF));
// Interpolation with periodic x-coordinates:
// >>> x = [-180, -170, -185, 185, -10, -5, 0, 365]
// >>> xp = [190, -190, 350, -350]
// >>> fp = [5, 10, 3, 4]
// >>> np.interp(x, xp, fp, period=360)
// array([7.5, 5., 8.75, 6.25, 3., 3.25, 3.5, 3.75])
//
//var x = [-180, -170, -185, 185, -10, -5, 0, 365];
var x = new float[] { -180, -170, -185, 185, -10, -5, 0, 365 };
xp = new float[] { 190, -190, 350, -350 };
fp = new float[] { 5, 10, 3, 4 };
given = np.interp(x, xp, fp, period: 360);
expected =
"array([7.5 , 5. , 8.75, 6.25, 3. , 3.25, 3.5 , 3.75])";
Assert.AreEqual(expected, given.repr);
// Complex interpolation:
// >>> x = [1.5, 4.0]
// >>> xp = [2,3,5]
// >>> fp = [1.0j, 0, 2+3j]
// >>> np.interp(x, xp, fp)
// array([ 0.+1.j , 1.+1.5j])
x = new float[] { 1.5f, 4.0f };
xp = new float[] { 2, 3, 5 };
var fp2 = new [] { new Complex(0, 1), new Complex(0, 0), new Complex(2, 3) };
given = np.interp(x, xp, fp2);
expected =
"array([0.+1.j , 1.+1.5j])";
Assert.AreEqual(expected, given.repr);
} |
Released to nuget as as Numpy v3.11.1.35 (1f35173) |
Nice work,Since it's 1:00 AM in China right now,I will bring your reply when I wake up and fire up my workstation,good night: ) |
Hi.I'm back here. I've met a new problem with new version of Numpy.NET is that:when i running up the program,it will throw an warning message: Could not find platform dependent libraries <exec_prefix> And then,when i call a numpy array in program,it may cause: PythonEngine is not initialized |
It won't happend on 3.10.1.30 release |
I am pretty sure that you are doing something wrong. I updated the MatmulExample in the Numpy.NET source code to use the latest numpy library and ran it and it works just fine: Output:
Sure it also prints the I don't have time to debug your app so here is my advice. Use the MatmulExample as a base and add your code. Maybe that'll work for you. |
Oh i see,My Anaconda base is Py3.10. Is that a related reason? |
Yes, that would explain it. I can backport the change onto a 3.10 version of numpy. |
Hi:
i've there's a testing code at:
Numpy.NET/test/Numpy.UnitTest/NumPy_math.tests.cs
Line 3388 in 5955d0c
Yet when i wanna using this function in project,it raised:
It raise it's not defined.
The text was updated successfully, but these errors were encountered: