General question about operations on list of numbers

Nov 29, 2012 at 1:06pm

General question about operations on list of numbers

Hello,

I want to get a list of numbers into my object and perform some operations on these numbers.

Each operation will create new values.

I am seeking a general advice: would you store each lists as an atom, convert the data to longs of doubles only for the calculations and then store the data back into atoms after each operation or would you rather convert the incoming data into regular C arrays, perform all the calculations and put the data into an atom only when you send them to the output ?

Thank you in advance.

#65429
Nov 29, 2012 at 2:47pm

Hi,

The list is persistent between calls ?
The operations are intensive ?
There is a maximum number of elements in the list ?

Try first to get a short and readable code.

#235758
Nov 29, 2012 at 3:43pm

Hi,

For example in my [zoulou], I pre-allocate an array of long (in the heap) as a cache :

x->values = (long *)sysmem_newptr(sizeof(long) * MAXIMUM_SIZE_LIST);

Then i use it to send/get values to/from my algorithm :

void zoulou_learn(t_zoulou *x, t_symbol *s, long argc, t_atom *argv)
{
    LOCK

    atom_getlong_array(argc, argv, MIN(argc, MAXIMUM_SIZE_LIST), x->values);
    pizFactorOracleAdd(x->factorOracle, MIN(argc, MAXIMUM_SIZE_LIST), x->values);

    UNLOCK
}

void zoulou_int(t_zoulou *x, long n)
{
    char alloc;
    t_atom *argv = NULL;
    long argc = 0;

    if ((n > 0) && !(atom_alloc_array(MIN(n, MAXIMUM_SIZE_LIST), &argc, &argv, &alloc))) {
    //
    PIZError err = PIZ_ERROR;

    LOCK

    if (pizFactorOracleCount(x->factorOracle)) {
        if (!(err = pizFactorOracleProceed(x->factorOracle, argc, x->values))) {
            atom_setlong_array(argc, argv, argc, x->values);
        }
    }

    UNLOCK

    if (!err) {
        outlet_list(x->leftOutlet, NULL, argc, argv);
    }

    sysmem_freeptr(argv);
    //
    }
}

Of course, just a way ; can be done differently in other situations.

https://github.com/nicolasdanet/Grenadine/blob/master/Sources/Various/zoulou/zoulou.c

I like to search in “Jamoma” sources for inspirations : https://github.com/jamoma/Jamoma ;-)

#235759
Nov 29, 2012 at 7:49pm

Hello Nicolas,

This is how I am doing it. Currently I am putting data into an array of long integers and then I put the outcome list in an atom just before sending it to output. What do you think about it ?

Another source for… …sources – especially when it comes to lists – are Peter Elsea’s lobjects. But I don’t understand everything. Pointers and friends are still giving me headaches. Aargl.

void rb_mebiii_list(t_rb_mebiii *x, t_symbol *s, short ac, t_atom *av)
{
	short performable ;

	if (ac >= 6) {																				// performs if list has six items at least
		short i;

		for (i=0 ; i < 6; i++) {
			postatom(&av[i]);
			if (atom_gettype(av)==A_LONG) {														// checks type (expected : long)

				// fills array of coordinates with values from list
				x->pointsRoughCoords[i] = atom_getlong(av);
				if (x->pointsRoughCoords[i] >= 0 && x->pointsRoughCoords[i] < = 1023) {	// checks value (expected : 0... ...1023)
					performable = 1;
				}
				else {
					performable = 0;
				}
			}
			else {
				post("rb.mebiii: element at position %i is not an integer !", i+1);
				performable = 0;
				break;
			}
		}

		if (performable == 1) {
			t_atom myList[3];
			filterPoints(x);
			averagePoints(x);
			calculateDistances(x);
			sortDistancesAndGetRoughZ(x);
			calibrateZ(x);
			x->output_list[0] = x->xPosition;
			x->output_list[1] = x->yPosition;
			x->output_list[2] = x->calibratedZPosition;

			for (i=0; i < 3; i++) {							// transferts data into t_atom
				atom_setfloat(myList+i,x->output_list[i]);
			}
			outlet_list(x->outlet1,0L,3,myList);
		}
		else {
			post("rb.mebiii: wrong data - cannot operate !");
		}

	}
	else {
		post("rb.mebiii: a list with %i elements is too short", ac);
	}
}
#235760
Nov 30, 2012 at 7:37am

Hi,

I can see few errors …

if (atom_gettype(av)==A_LONG) {
...
x->pointsRoughCoords[i] = atom_getlong(av);
...
else {
   performable = 0;
}

… should be …

if (atom_gettype(av + i) == A_LONG) {
...
x->pointsRoughCoords[i] = atom_getlong(av + i);
...
else {
   performable = 0;
   break;
}

… and then, using “output_list” directly …

typedef struct _rb_mebiii {
    t_object ob;
    t_atom output_list[3];
} t_rb_mebiii;

void rb_mebiii_list(t_rb_mebiii *x, t_symbol *s, short ac, t_atom *av)
{
    if (ac >= 6) {
    //
    short i;
    short err = 0;

    for (i = 0; i < 6; i++) {
        if (atom_gettype(av + i) == A_LONG) {
            x->pointsRoughCoords[i] = atom_getlong(av + i);
            if (!(x->pointsRoughCoords[i] >= 0 && x->pointsRoughCoords[i] < = 1023)) {
                err = 1;
                break;
            }
        } else {
            post("rb.mebiii: element at position %i is not an integer !", i + 1);
            err = 1;
            break;
        }
    }

    if (!err) {

        filterPoints(x);
        averagePoints(x);
        calculateDistances(x);
        sortDistancesAndGetRoughZ(x);
        calibrateZ(x);

        atom_setfloat(x->output_list + 0, x->xPosition);
        atom_setfloat(x->output_list + 1, x->yPosition);
        atom_setfloat(x->output_list + 2, x->calibratedZPosition);

        outlet_list(x->outlet1, 0L, 3, x->output_list);

    } else {
        post("rb.mebiii: wrong data - cannot operate !");
    }

    //
    } else {
        post("rb.mebiii: a list with %i elements is too short", ac);
    }
}

… untested code ;-)

#235761
Nov 30, 2012 at 8:02am

Thanks a lot for your help, Nicolas.

#235762

You must be logged in to reply to this topic.