Select Git revision
utils.cs 3.94 KiB
using System;
using System.Runtime.InteropServices;
namespace Kiss
{
/// <summary>
/// This class is a collection of static methods usefull for use with kissinference.
/// </summary>
public class Utils
{
static private bool EnviromentChecked = false;
/// <summary>
/// Converts an array containing a linear or log range.
/// </summary>
/// <param name="start">
/// The startig value of the range.
/// </param>
/// <param name="end">
/// The ending value of the range.
/// </param>
/// <param name="size">
/// The number of elements in the range.
/// </param>
/// <param name="log">
/// If this is set to true the elements in the range are spaced in log10 fashion, otherwise linear spaceing is used.
/// </param>
/// <returns>
/// An array containing the requested range
/// </returns>
public static float[] CreateRange(float start, float end, int size, bool log)
{
CheckEnvThrow();
IntPtr ptr = Capi.kiss_create_range(start, end, (UIntPtr)size, Convert.ToByte(log));
var ret = new float[size];
Marshal.Copy(ptr, ret, 0, size);
Capi.free(ptr);
return ret;
}
/// <summary>
/// Approximates the the derivative of an array at the given index.
/// </summary>
/// <param name="data">
/// The array, or y values, to approximate the derivative on
/// </param>
/// <param name="omegas">
/// The omega, or x values to approximate the derivative on
/// </param>
/// <param name="index">
/// The index at which to aproxmiate the gradiant at.
/// </param>
/// <returns>
/// The aproxmiate derivative.
/// </returns>
public static float Grad(float[] data, float[] omegas, int index)
{
CheckEnvThrow();
if(data.Length != omegas.Length)
throw new ArgumentException("the data and omegas must be the same length");
return Capi.kiss_grad(data, omegas, (UIntPtr)data.Length, (UIntPtr)index);
}
/// <summary>
/// Calculates the median of the values given
/// </summary>
/// <param name="input">
/// The input array.
/// </param>
/// <returns>
/// The median value
/// </returns>
public static float Median(float[] data)
{
CheckEnvThrow();
return Capi.kiss_median(data, (UIntPtr)data.Length);
}
/// <summary>
/// Checks the given floats for equality with a tollerance of ulp epsilons around the sum of the inputs.
/// </summary>
/// <param name="a">
/// The first paramter for the comperasin
/// </param>
/// <param name="b">
/// b The second input to be compared with the first.
/// </param>
/// <param name="ulp">
/// lp number of epsilons of tollerance..
/// </param>
/// <returns>
/// True if the value of b is within ulp epsilons of a, false otherwise.
/// </returns>
public static bool FloatEq(float a, float b, uint ulp)
{
CheckEnvThrow();
return Capi.kiss_float_eq(a, b, ulp) != 0;
}
/// <summary>
/// Checks the envirment to see if this libary can work correctly
/// </summary>
/// <returns>
/// string.Empty if the environment is acceptable and an error message if it is not.
/// </returns>
public static string CheckEnv()
{
if(EnviromentChecked)
return string.Empty;
if(System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture != Architecture.X86 &&
System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture != Architecture.X64)
return "libkissinferencesharp only works on X86 or X64 cpu architecture";
var version = VersionFixed.GetVersionNoCheck();
if(version.Major != 1 || version.Minor != 1)
return "This version of libkissinferencesharp only supports native code backends of version 1.1.x, but the loaded libary is " + version;
EnviromentChecked = true;
return string.Empty;
}
/// <summary>
/// Checks the envirment to see if this libary can work correctly and throws a EnviromentException if its not.
/// </summary>
/// <exception cref="Kiss.EnviromentException">
/// Thown if the environment is unacceptable.
/// </exception>
public static void CheckEnvThrow()
{
var res = CheckEnv();
if(res.Length == 0)
return;
throw new EnviromentException(res);
}
}
}