SoloCodigo

CLR: .Net / Mono / Boo / Otros CLR => C# => Mensaje iniciado por: patpite en Domingo 10 de Abril de 2005, 21:07

Título: Código Unsafe
Publicado por: patpite en Domingo 10 de Abril de 2005, 21:07
Hola,

¿Alguien podría decirme cómo se introduce código de c++ en una aplicación c#? ¿tiene muchos inconvenientes?

Saludos,

Patricia.
Título: Re: Código Unsafe
Publicado por: JuanK en Domingo 10 de Abril de 2005, 22:14
y... para que? :scream:
Título: Re: Código Unsafe
Publicado por: patpite en Domingo 17 de Abril de 2005, 21:06
Pues a ver... tengo que meter en un programa que he hecho yo una parte de código que ya ha sido creada (en concreto, el algoritmo amoeba, del Numerical Recipes). Este código lo tengo escrito en Visual Basic, Fortran y C. Y el de C lleva punteros.

Tengo que "adaptarlo" para C#, y como no me funciona, he pensado que posiblemente sea porque necesita del uso del punteros. Pero el caso es que ni en VB ni en Fortran los emplea.

¿Alguna sugerencia?

Gracias.

Patri.
Título: Re: Código Unsafe
Publicado por: JuanK en Martes 19 de Abril de 2005, 14:22
cualuier cosa has ta donde se.. que este hecha con punteros la puedes convertir al uso de arrays  o colecciones en C#, seria interesante revisar el codigo de C que debes pasar a C# a ver que hiciste mal y que se peude hacer.

El codigo unsafe es muy poco recomendable.
Título: Re: Código Unsafe
Publicado por: patpite en Sábado 23 de Abril de 2005, 19:49
Bueno... esta es la página donde viene el algoritmo que he empleado. Se llama "amoeba": sirve para minimizar funciones. Aquí viene codificado en Fortran y en C. (También lo encontré en VB).

Algortimo Amoeba (http://www.library.cornell.edu/nr/bookcpdf/c10-4.pdf)


Y mi codificación en C# del amoebilla ha sido la siguiente (al que se moleste en echarle un vistazo y me diga si hay un error o algo que no cuadre, le hago un monumento!!!!)
Código: Text
  1.  
  2. using System;
  3. using System.Data;
  4. using System.Data.OleDb;
  5. using System.ComponentModel;
  6. using System.Windows.Forms;
  7. using Andromeda.clases;
  8.  
  9.  
  10. namespace Andromeda.clases
  11. {
  12.   /// <summary>
  13.   /// Descripción breve de Amoeba.
  14.   /// </summary>
  15.  
  16.   public class Amoeba
  17.   {
  18.  
  19. /* Definiciones de Variables y Constantes*/    
  20.    
  21. public Amoeba(){}
  22.  
  23. /* Devuelve punto de evaluacion*/
  24. public static void Get_Msum(int n,double[] Msum)
  25. {
  26.   int ndim = n;  // Curva oscuridad, n = 6; mpts = 7
  27.   int mpts = ndim + 1;  
  28.   double sum;
  29.   int i;
  30.  
  31.   for(int j=0;j<=ndim-1;j++)  // Recorre las 6 columnas de M
  32.   {
  33.      for(sum = 0.0, i=0;i<=mpts-1;i++)  // Recorre las 7 filas de M
  34.     sum = sum + Andromeda.clases.comun.M[i,j];
  35.     Msum[j]=sum;    //Msum tiene 6 posiciones
  36.      }
  37.   }
  38.  
  39.  
  40. /* Intercambio de valores*/
  41. public static void SWAP(double a, double B)
  42. {
  43.   double aux = 0;
  44.   aux = a;
  45.   a = b;
  46.   b = aux;
  47. }
  48.  
  49.  
  50.  
  51. /* Función "Amotry"*/
  52. public static double amotry(int ident,double cte,double[,] M,double[] y,double Msum,int n,int ihi,int nfunk,double fac)
  53. {
  54.   int j;
  55.   double fac1; double fac2;
  56.   double ytry;
  57.   double[] ptry;
  58.  
  59.   int ndim = n;
  60.  
  61.   ptry = new double[ndim+1];
  62.   fac1 = (1.0-fac)/ndim;
  63.   fac2 = fac1-fac;
  64.  
  65.   for(j=0;j<=ndim-1;j++)
  66.       ptry[j]=Msum[j]*fac1-M[ihi,j]*fac2;
  67.  
  68.   ytry = Andromeda.clases.comun.funcionE(ident,cte,ptry); //Función a minimizar
  69.  
  70.   if(ytry < y[ihi])
  71.   {
  72.                    y[ihi]=ytry;
  73.      for(j=0;j<=ndim-1;j++)
  74.      {
  75.          Msum[j] = Msum[j] + ptry[j]-M[ihi,j];
  76.          M[ihi,j]= ptry[j];
  77.      }
  78.   }
  79.  
  80.   return ytry;
  81.   }//endmethod
  82.  
  83.  
  84. /*FUNCION "amoeba" */
  85. public static void amoeba(int ident,double cte,double[,] M,double[] y,int ndim,double ftol)
  86. {
  87.   // Zona de declaración de variables
  88.   int i,ihi,ilo,inhi,j,mpts;
  89.   double rtol,ysave,ytry; // sum?
  90.   int nfunk;
  91.      
  92.   // Zona de declaración de constantes
  93.   const int NMAX = 5000;
  94.   const int ITMAX = 100;
  95.   const double TINY = 1.0E-10;
  96.  
  97.   // Zona de inicialización de variables
  98.   double[] Msum = new double[ndim+1];
  99.   mpts = ndim +1;
  100.   nfunk = 0;
  101.  
  102.   Get_Msum(ndim,Msum);    
  103.  
  104.   for(;;)
  105.   {
  106.         ilo = 0;
  107.  
  108.      if(y[0]>y[1])
  109.      {
  110.          inhi = 1;
  111.          ihi = 0;
  112.       }
  113.      else
  114.      {
  115.          inhi = 0;
  116.          ihi = 1;
  117.      }
  118.  
  119.                    for(i=0; i<=mpts-1; i++)
  120.      {
  121.          if(y[i] <= y[ilo]) ilo = i;
  122.          if(y[i]>y[ihi])
  123.          {
  124.     inhi = ihi;
  125.     ihi = i;
  126.          }else if(y[i]>y[inhi] && i!=ihi) inhi = i;
  127.       }//endfor
  128.  
  129.   rtol = 2.0*Math.Abs(y[ihi]-y[ilo])/(Math.Abs(y[ihi])+Math.Abs(y[ilo])+TINY);
  130.  
  131.   if(rtol < ftol)
  132.   {
  133.             SWAP(y[0],y[ilo]);
  134.          for(i=0; i<=ndim-1; i++)
  135.     SWAP(M[0,i],M[ilo,i]);
  136.          break;
  137.                 }//endif
  138.  
  139.   if( nfunk >= NMAX)
  140.   {
  141.           // EN CASO DE ERROR:
  142.     return;
  143.                 }  
  144.  
  145.                 nfunk= nfunk+2;
  146.  
  147.   // Aquí comienza una nueva iteración
  148.   ytry = amotry(ident,cte,M,y,Msum,ndim,ihi,nfunk,-1.0);
  149.        
  150.   if(ytry <= y[ilo])
  151.   {
  152.            ytry = amotry(ident,cte,M,y,Msum,ndim,ihi,nfunk,2.0);
  153.   }
  154.   else if(ytry >= y[inhi])
  155.   {
  156.            ysave = y[ihi];
  157.            ytry = amotry(ident,cte,M,y,Msum,ndim,ihi,nfunk,0.5);
  158.  
  159.            if(ytry >= ysave)
  160.            {
  161.     for(i=0; i<=mpts-1; i++)
  162.     {
  163.           if(i!=ilo)
  164.          {
  165.               for(j=0; j<=ndim-1; j++)
  166.       M[i,j] = Msum[j]=0.5*(M[i,j]+M[ilo,j]);
  167.  
  168.                                            y[i] = Andromeda.clases.comun.funcionE(ident,cte,Msum);
  169.                                      }//endif
  170.     }//endfor
  171.  
  172.                  nfunk = nfunk + ndim;
  173.                  Get_Msum(ndim,Msum);
  174.                }//endif
  175.  
  176.   }//endif
  177.  
  178.   else --nfunk;
  179.  
  180.            }//endfor
  181.  
  182.      }
  183. }
  184.  
Título: Re: Código Unsafe
Publicado por: patpite en Lunes 25 de Abril de 2005, 10:24
Otro detalle: la función que ese algoritmo trata de minimizar es la siguiente (aunque he quitado código que entorpecería ver la "esencia" de la función):

Código: Text
  1. /***********************************************************************************
  2.    *          Método que implementa la función error: E       *
  3.    ***********************************************************************************/
  4.     public static double funcionE(int ident,double cte,double p1,double p2,double p3,double
  5.               p4,double p5,double p6)
  6.     {
  7.       double Iteor = 0;
  8.       double Err = 0;
  9.    
  10.       double T = Temperatura;
  11.       double Vexp;
  12.       double Iexp;
  13.  
  14.       for(int j=0; j<Mpuntos-N;j++)
  15.       {
  16.         Vexp = (double)puntosGrupo[ident][0,j];
  17.         Iexp = (double)puntosGrupo[ident][1,j];
  18.  
  19.        
  20.         // Calculo la Iteor
  21.         Iteor = Math.Abs(cte - ( p1*(Math.Exp((e*Vexp-p5*Iexp)/p3*k*T)-1) +
  22.               p2*(Math.Exp((e*Vexp-p5*Iexp)/p4*k*T)-1) + (Vexp-p5*Iexp)/p6 ));
  23.         // Calculo el error para ese punto concreto
  24.         Err = Math.Pow(((Iexp-Iteor)/Iexp),2);
  25.         // Lo sumo a la func. error global para el grupo tratado
  26.         funcE = funcE + Err;
  27.        
  28.  
  29.       }//endfor
  30.  
  31. return funcE;
  32.  
  33.     }//endmethod
  34.  


He visto que no parece cargar bien en "funcE" lo que calcula en "Err". He hecho alguna prueba relacionada con "limpiar" el contenido de algunas variables, pero no doy con la solución. ¿Alguna sugerencia, por favor?

Saludos,

Patricia, a punto de ahorcarse con el cable de red.