/************************************************************************* AP library Copyright (c) 2003-2009 Sergey Bochkanov (ALGLIB project). >>> LICENSE >>> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation (www.fsf.org); either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. A copy of the GNU General Public License is available at http://www.fsf.org/licensing/licenses >>> END OF LICENSE >>> *************************************************************************/ using System; public partial class alglib { /******************************************************************** Callback definitions for optimizers/fitters/solvers. Callbacks for unparameterized (general) functions: * ndimensional_func calculates f(arg), stores result to func * ndimensional_grad calculates func = f(arg), grad[i] = df(arg)/d(arg[i]) * ndimensional_hess calculates func = f(arg), grad[i] = df(arg)/d(arg[i]), hess[i,j] = d2f(arg)/(d(arg[i])*d(arg[j])) Callbacks for systems of functions: * ndimensional_fvec calculates vector function f(arg), stores result to fi * ndimensional_jac calculates f[i] = fi(arg) jac[i,j] = df[i](arg)/d(arg[j]) Callbacks for parameterized functions, i.e. for functions which depend on two vectors: P and Q. Gradient and Hessian are calculated with respect to P only. * ndimensional_pfunc calculates f(p,q), stores result to func * ndimensional_pgrad calculates func = f(p,q), grad[i] = df(p,q)/d(p[i]) * ndimensional_phess calculates func = f(p,q), grad[i] = df(p,q)/d(p[i]), hess[i,j] = d2f(p,q)/(d(p[i])*d(p[j])) Callbacks for progress reports: * ndimensional_rep reports current position of optimization algo Callbacks for ODE solvers: * ndimensional_ode_rp calculates dy/dx for given y[] and x Callbacks for integrators: * integrator1_func calculates f(x) for given x (additional parameters xminusa and bminusx contain x-a and b-x) ********************************************************************/ public delegate void ndimensional_func (double[] arg, ref double func, object obj); public delegate void ndimensional_grad (double[] arg, ref double func, double[] grad, object obj); public delegate void ndimensional_hess (double[] arg, ref double func, double[] grad, double[,] hess, object obj); public delegate void ndimensional_fvec (double[] arg, double[] fi, object obj); public delegate void ndimensional_jac (double[] arg, double[] fi, double[,] jac, object obj); public delegate void ndimensional_pfunc(double[] p, double[] q, ref double func, object obj); public delegate void ndimensional_pgrad(double[] p, double[] q, ref double func, double[] grad, object obj); public delegate void ndimensional_phess(double[] p, double[] q, ref double func, double[] grad, double[,] hess, object obj); public delegate void ndimensional_rep(double[] arg, double func, object obj); public delegate void ndimensional_ode_rp (double[] y, double x, double[] dy, object obj); public delegate void integrator1_func (double x, double xminusa, double bminusx, ref double f, object obj); /******************************************************************** Class defining a complex number with double precision. ********************************************************************/ public struct complex { public double x; public double y; public complex(double _x) { x = _x; y = 0; } public complex(double _x, double _y) { x = _x; y = _y; } public static implicit operator complex(double _x) { return new complex(_x); } public static bool operator==(complex lhs, complex rhs) { return ((double)lhs.x==(double)rhs.x) & ((double)lhs.y==(double)rhs.y); } public static bool operator!=(complex lhs, complex rhs) { return ((double)lhs.x!=(double)rhs.x) | ((double)lhs.y!=(double)rhs.y); } public static complex operator+(complex lhs) { return lhs; } public static complex operator-(complex lhs) { return new complex(-lhs.x,-lhs.y); } public static complex operator+(complex lhs, complex rhs) { return new complex(lhs.x+rhs.x,lhs.y+rhs.y); } public static complex operator-(complex lhs, complex rhs) { return new complex(lhs.x-rhs.x,lhs.y-rhs.y); } public static complex operator*(complex lhs, complex rhs) { return new complex(lhs.x*rhs.x-lhs.y*rhs.y, lhs.x*rhs.y+lhs.y*rhs.x); } public static complex operator/(complex lhs, complex rhs) { complex result; double e; double f; if( System.Math.Abs(rhs.y)(T[] a) { return a.Length; } public static int rows(T[,] a) { return a.GetLength(0); } public static int cols(T[,] a) { return a.GetLength(1); } public static void swap(ref T a, ref T b) { T t = a; a = b; b = t; } public static void assert(bool cond, string s) { if( !cond ) throw new alglibexception(s); } public static void assert(bool cond) { assert(cond, "ALGLIB: assertion failed"); } /**************************************************************** returns dps (digits-of-precision) value corresponding to threshold. dps(0.9) = dps(0.5) = dps(0.1) = 0 dps(0.09) = dps(0.05) = dps(0.01) = 1 and so on ****************************************************************/ public static int threshold2dps(double threshold) { int result = 0; double t; for (result = 0, t = 1; t / 10 > threshold*(1+1E-10); result++, t /= 10) ; return result; } /**************************************************************** prints formatted array ****************************************************************/ public static string format(bool[] a) { string[] result = new string[len(a)]; int i; for(i=0; i= 0 ? "+" : "-") + String.Format(fmty, Math.Abs(a[i].y)) + "i"; result[i] = result[i].Replace(',', '.'); } return "{" + String.Join(",", result) + "}"; } /**************************************************************** prints formatted matrix ****************************************************************/ public static string format(bool[,] a) { int i, j, m, n; n = cols(a); m = rows(a); bool[] line = new bool[n]; string[] result = new string[m]; for (i = 0; i < m; i++) { for (j = 0; j < n; j++) line[j] = a[i, j]; result[i] = format(line); } return "{" + String.Join(",", result) + "}"; } /**************************************************************** prints formatted matrix ****************************************************************/ public static string format(int[,] a) { int i, j, m, n; n = cols(a); m = rows(a); int[] line = new int[n]; string[] result = new string[m]; for (i = 0; i < m; i++) { for (j = 0; j < n; j++) line[j] = a[i, j]; result[i] = format(line); } return "{" + String.Join(",", result) + "}"; } /**************************************************************** prints formatted matrix ****************************************************************/ public static string format(double[,] a, int dps) { int i, j, m, n; n = cols(a); m = rows(a); double[] line = new double[n]; string[] result = new string[m]; for (i = 0; i < m; i++) { for (j = 0; j < n; j++) line[j] = a[i, j]; result[i] = format(line, dps); } return "{" + String.Join(",", result) + "}"; } /**************************************************************** prints formatted matrix ****************************************************************/ public static string format(complex[,] a, int dps) { int i, j, m, n; n = cols(a); m = rows(a); complex[] line = new complex[n]; string[] result = new string[m]; for (i = 0; i < m; i++) { for (j = 0; j < n; j++) line[j] = a[i, j]; result[i] = format(line, dps); } return "{" + String.Join(",", result) + "}"; } /**************************************************************** checks that matrix is symmetric. max|A-A^T| is calculated; if it is within 1.0E-14 of max|A|, matrix is considered symmetric ****************************************************************/ public static bool issymmetric(double[,] a) { int i, j, n; double err, mx, v1, v2; if( rows(a)!=cols(a) ) return false; n = rows(a); if( n==0 ) return true; mx = 0; err = 0; for( i=0; iyabs ? xabs : yabs; v = xabs