Pregunta

Estoy trabajando en una función para establecer la entropía de una distribución.Utiliza una cópula, si alguno está familiarizado con ella.Necesito resumir los valores de la matriz en función de las dimensiones que "se preocupan".

Ejemplo:Considere el siguiente ejemplo...

Dimension 0 (across)
_ _ _ _ _ _ _ _ _ _ _ _ _
|_ 0 _|_ 0 _|_ 0 _|_ 2 _|  Dimension 1
|_ 1 _|_ 0 _|_ 2 _|_ 0 _|   (down)
|_ 0 _|_ 3 _|_ 0 _|_ 6 _|
|_ 0 _|_ 0 _|_ 0 _|_ 0 _|

I "care about" dimension 0 only, and "don't care" about the rest (dim 1).
Summing this array with the above specifications will
"collapse" the "stacks" of dimension 1 down to a single 4 x 1 array:

_ _ _ _ _ _ _ _ _ _ _ _ _ 
|_ 1 _|_ 3 _|_ 2 _|_ 8 _|

This can then be summed, or have any operation performed.

Necesito hacer esto con una serie de 'n' dimensiones, que posiblemente podrían ser 20.Además, necesito poder hacer esto, preocupándome por ciertas dimensiones y colapsando el resto.Estoy teniendo un momento especialmente difícil con esto porque no puedo visualizar 20 dimensiones :p.Si alguien pudiera ayudarme a configurar algún código c/c++ para contraer/suma, estaría muy, muy agradecido.

Actualizar:

Acabo de llegar a casa.Aquí te dejamos información para responder a tus preguntas:

  1. Perdón por revertir las ediciones, esperaba que cuando hiciera clic en revertir me mostrara los cambios para poder ver en qué me equivoqué, un poco como Wikipedia.Este no fue el caso, según descubrí.
  2. @jeff: ¿Qué no tiene sentido?Estoy usando este gran servicio por (lo que creo que es) una razón legítima.Quiero mejorar en mi pasatiempo, que es todo, ya que estoy en la escuela secundaria.Muchas de mis publicaciones tratan sobre la implementación de un algoritmo genético (esta publicación, sparsearray, clasificación de una matriz, manipulación de punteros).
  3. Estoy usando una representación de matriz dispersa, ya que es posible exceder la cantidad de moléculas en el universo usando una matriz tradicional (densa).Por ahora, la implementación del sparsearray en sí no importa mucho, ya que estoy trabajando para que funcione con un array estándar antes de pasar a una representación dispersa.Para aquellos que no han visto mis preguntas anteriores, estoy usando un árbol de búsqueda binario como estructura para contener los puntos dispersos de la matriz y una función "controladora" para recorrer el árbol según sea necesario, devolviendo lo que sea que la función esté diseñada para hacer.Esto es flexible, por lo que puedo adaptar muchos métodos diferentes para acceder a la matriz.
  4. La estructura es un hipercubo y el número de dimensiones se especifica en tiempo de ejecución, así como la longitud de cada dimensión (que son todas iguales, al ser un hipercubo).

Gracias a todos por su aporte.

¿Fue útil?

Solución

Esto podría tener aplicaciones.Digamos que implementó un Juego de la vida de Conway 2D (que define un plano 2D, 1 para "vivo", 0 para "muerto") y almacenó el historial de juegos para cada iteración (que luego define un cubo 3D).Si quisieras saber cuántas bacterias hubo vivas a lo largo de la historia, usarías el algoritmo anterior.Podrías usar el mismo algoritmo para una versión 3D (y 4D, 5D, etc.) de la cuadrícula de Game of Life.

Yo diría que esta es una pregunta de recursividad, todavía no soy programador de C pero sé que es posible en C.En pitón,


def iter_arr(array):
  sum = 0
  for i in array:
    if type(i) == type(list()):
      sum = sum + iter_arr(i)
    else:
      sum = sum + i
  return sum 
  1. Iterar sobre cada elemento de la matriz
  2. Si el elemento es otra matriz, llame a la función nuevamente
  3. Si el elemento no es una matriz, agréguelo a la suma
  4. Suma de devolución

Luego aplicaría esto a cada elemento en la dimensión "preocupado".

Sin embargo, esto es más fácil en Python debido a la escritura pato...

Otros consejos

@Jeff

De hecho, creo que esta es una pregunta interesante.No estoy seguro de qué tan útil sea, pero es una pregunta válida.

@Ed

¿Puedes proporcionar un poco más de información sobre esta pregunta?Dijiste que la dimensión de la matriz es dinámica, pero ¿la cantidad de elementos también es dinámica?

EDITAR:Voy a intentar responder la pregunta de todos modos.No puedo darte el código que se me viene a la cabeza (me llevaría un tiempo hacerlo bien sin ningún compilador aquí en esta PC), pero puedo indicarte la dirección correcta...

Usemos 8 dimensiones (0-7) con índices 0 a 3 como ejemplo.Sólo te importan 1, 2 y 6.Esto significa que tienes dos matrices.Primero, array_care[4][4][4] para 1, 2 y 6.El array_care[4][4][4] mantendrá el resultado final.

A continuación, queremos iterar de una manera muy específica.tenemos la matriz input[4][4][4][4][4][4][4][4] para analizar, y nos preocupamos por las dimensiones 1, 2 y 6.

Necesitamos definir algunos índices temporales:

int dim[8] = {0,0,0,0,0,0,0,0};

También necesitamos almacenar el orden en el que queremos aumentar los índices:

int increase_index_order[8] = {7,5,4,3,0,6,2,1};
int i = 0;

Este orden es importante para hacer lo que usted solicitó.

Defina una bandera de terminación:

bool terminate=false;

Ahora podemos crear nuestro bucle:

while (terminate)
{
array_care[dim[1]][dim[2]][dim[6]] += input[dim[0]][dim[1]][dim[2]][dim[3]][dim[4]][dim[5]][dim[6]][dim[7]];

while ((dim[increase_index_order[i]] = 3) && (i < 8))
{
dim[increase_index_order[i]]=0;
i++;
}

if (i < 8) {
dim[increase_index_order[i]]++; i=0;
} else {
terminate=true;
}
}

Eso debería funcionar para 8 dimensiones, preocupándose por 3 dimensiones.Se necesitaría un poco más de tiempo para dinamizarlo y no tengo tiempo.Espero que esto ayude.Pido disculpas, pero aún no he aprendido las marcas del código.:(

Este tipo de cosas es mucho más fácil si usas contenedores STL, o tal vez Impulso.MultiArray.Pero si debes usar una matriz:

#include <iostream>
#include <boost/foreach.hpp>
#include <vector>

int sum(int x) {
    return x;
}

template <class T, unsigned N>
int sum(const T (&x)[N]) {
    int r = 0;
    for(int i = 0; i < N; ++i) {
        r += sum(x[i]);
    }
    return r;
}

template <class T, unsigned N>
std::vector<int> reduce(const T (&x)[N]) {
    std::vector<int> result;
    for(int i = 0; i < N; ++i) {
        result.push_back(sum(x[i]));
    }
    return result;
}

int main() {
    int x[][2][2] = {
        { { 1, 2 }, { 3, 4 } },
        { { 5, 6 }, { 7, 8 } }
    };

    BOOST_FOREACH(int v, reduce(x)) {
        std::cout<<v<<"\n";
    }
}

En realidad, al contraer las columnas ya las sumaste, por lo que la dimensión no importa en absoluto para tu ejemplo.¿Me perdí algo o a ti?

Creo que lo mejor que se puede hacer aquí sería una o ambas cosas:

  1. Reconsidere el diseño; si es demasiado complejo, busque una forma menos compleja.
  2. Deja de intentar visualizarlo...:P Simplemente almacene las dimensiones en cuestión que necesita sumar, luego hágalas una a la vez.Una vez que tenga el código base, busque mejorar la eficiencia de su algoritmo.

No estoy de acuerdo, SIEMPRE hay otra manera.

Y si realmente no puedo refactorizar, entonces necesitas dividir el problema en partes más pequeñas.Como dije, establezca qué dimensiones necesita sumar y luego golpéelas una a la vez.

Además, deja de cambiar las ediciones, están corrigiendo tus errores ortográficos, están tratando de ayudarte;)

Estás haciendo esto en c/c++...entonces tienes una matriz de matriz de matriz...no es necesario visualizar 20 dimensiones ya que no es así como se distribuyen los datos en la memoria, para una dimensión bidimensional:

[1] --> [1,2,3,4,5,6,...]
[2] --> [1,2,3,4,5,6,...]
[3] --> [1,2,3,4,5,6,...]
[4] --> [1,2,3,4,5,6,...]
[5] --> [1,2,3,4,5,6,...]
 .           .
 .           .
 .           .

Entonces, ¿por qué no puedes recorrer el primero sumando su contenido?Si estás tratando de encontrar el tamaño, entonces sizeof(array)/sizeof(int) es un enfoque arriesgado.Debe conocer la dimensión para poder procesar estos datos y configurar la memoria para saber la profundidad de la recursividad para sumar.Aquí hay un pseudocódigo de lo que parece que deberías hacer,

sum( n_matrix, depth )
  running_total = 0
  if depth = 0 then
    foreach element in the array
      running_total += elm
  else 
     foreach element in the array
       running_total += sum( elm , depth-1 )
  return running_total
x = number_of_dimensions;
while (x > 1)
{
  switch (x)
  {
    case 20:
      reduce20DimensionArray();
      x--;
    break;
    case 19:
      .....
  }
}

(Lo siento, no pude resistirme).

Si entiendo correctamente, desea sumar todos los valores en la sección transversal definida en cada "contenedor" a lo largo de 1 dimensión.Sugiero hacer una matriz 1D para su destino y luego recorrer cada elemento de su matriz agregando el valor al destino con el índice de la dimensión de interés.

Si está utilizando un número arbitrario de dimensiones, debe tener una forma de abordar los elementos (me gustaría saber cómo está implementando esto).La implementación de esto afectará la forma en que configura el índice de destino.Pero una forma obvia sería verificar las declaraciones if en los bucles de iteración.

Cuando dice que no sabe cuántas dimensiones hay, ¿cómo define exactamente las estructuras de datos?

En algún momento, alguien necesita crear esta matriz y, para hacerlo, necesita conocer las dimensiones de la matriz.Puede obligar al creador a pasar estos datos junto con la matriz.

A menos que la pregunta sea definir dicha estructura de datos...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top