Ejemplo n.º 1
0
    static boost::tuple<
        boost::shared_ptr<Matrix>,
        boost::shared_ptr<Matrix>
        >
    transfer_operators(const Matrix &A, params &prm)
    {
        typedef typename backend::value_type<Matrix>::type V;

        const size_t n = rows(A);

        TIC("aggregates");
        Aggregates aggr(A, prm.aggr, prm.nullspace.cols);
        TOC("aggregates");

        TIC("interpolation");
        boost::shared_ptr<Matrix> P = tentative_prolongation<Matrix>(
                n, aggr.count, aggr.id, prm.nullspace, prm.aggr.block_size
                );
        TOC("interpolation");

        boost::shared_ptr<Matrix> R = boost::make_shared<Matrix>();
        *R = transpose(*P);

        if (prm.nullspace.cols > 0)
            prm.aggr.block_size = prm.nullspace.cols;

        return boost::make_tuple(P, R);
    }
Ejemplo n.º 2
0
 std::tuple<
     std::shared_ptr< distributed_matrix<Backend> >,
     std::shared_ptr< distributed_matrix<Backend> >
     >
 transfer_operators(const distributed_matrix<Backend> &A) {
     pmis<Backend> aggr(A, prm.aggr);
     return std::make_tuple(aggr.p_tent, transpose(*aggr.p_tent));
 }
Ejemplo n.º 3
0
        pointwise_aggregates(const Matrix &A, const params &prm) : count(0)
        {
            if (prm.block_size == 1) {
                plain_aggregates aggr(A, prm);

                count = aggr.count;
                strong_connection.swap(aggr.strong_connection);
                id.swap(aggr.id);
            } else {
                strong_connection.resize( nonzeros(A) );
                id.resize( rows(A) );

                Matrix Ap = pointwise_matrix(A, prm.block_size);

                plain_aggregates pw_aggr(Ap, prm);
                count = pw_aggr.count * prm.block_size;

#pragma omp parallel
                {
                    std::vector<ptrdiff_t> marker(Ap.nrows, -1);

#ifdef _OPENMP
                    int nt  = omp_get_num_threads();
                    int tid = omp_get_thread_num();

                    size_t chunk_size  = (Ap.nrows + nt - 1) / nt;
                    size_t chunk_start = tid * chunk_size;
                    size_t chunk_end   = std::min(Ap.nrows, chunk_start + chunk_size);
#else
                    size_t chunk_start = 0;
                    size_t chunk_end   = Ap.nrows;
#endif

                    for(size_t ip = chunk_start, ia = ip * prm.block_size; ip < chunk_end; ++ip) {
                        ptrdiff_t row_beg = Ap.ptr[ip];
                        ptrdiff_t row_end = row_beg;

                        for(unsigned k = 0; k < prm.block_size; ++k, ++ia) {
                            id[ia] = prm.block_size * pw_aggr.id[ip] + k;

                            for(ptrdiff_t ja = A.ptr[ia], ea = A.ptr[ia+1]; ja < ea; ++ja) {
                                ptrdiff_t cp = A.col[ja] / prm.block_size;

                                if (marker[cp] < row_beg) {
                                    marker[cp] = row_end;
                                    strong_connection[ja] = pw_aggr.strong_connection[row_end];
                                    ++row_end;
                                } else {
                                    strong_connection[ja] = pw_aggr.strong_connection[ marker[cp] ];
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 4
0
int main() {
	FILE *neigh; 
	FILE *train;
	FILE *test;
	FILE *result;
	int user, movie, rating, time;
	long double pred;
	long double mae;
	int n;
	int user_pos;
	int cur_user;
	long double mae_list[500];
	int mae_i=0;
	test = fopen("new_testing.dat", "r");
	neigh = fopen("new_neighbours.dat", "r");
	train = fopen("new_training.dat", "r");
	result = fopen("result.dat", "w");
	
	while(!feof(test)) {
		fscanf(test, "%d::%d::%d::%d\n", &user, &movie, &rating, &time);
		mae  = 0.0;
		n = 0;
		cur_user = user;
		printf("\nFor user %d", cur_user);

		while(user==cur_user) {
			pred = aggr(user, movie, neigh, train);
			fprintf(result, "%d::%d::%llf\n", user, movie, pred);
			mae += fabsl(pred-rating);
			n++;
			user_pos=ftell(test);
			if(feof(test)) break;
			fscanf(test, "%d::%d::%d::%d\n", &user, &movie, &rating, &time);
		}
		mae = mae/((long double)(n));

		mae_list[mae_i++] = mae;
		if(feof(test)) break;
		fseek(test, user_pos, SEEK_SET);
	}
	
	mae = 0.0;
	for(n=0; n<mae_i; n++) 
		mae += mae_list[n];

	mae = mae/mae_i;
	fprintf(result, "MAE:%llf\n", mae);

	fclose(test);
	fclose(neigh);
	fclose(train);
	fclose(result);

	return 0;
}
Ejemplo n.º 5
0
    std::tuple<
        std::shared_ptr<Matrix>,
        std::shared_ptr<Matrix>
        >
    transfer_operators(const Matrix &A) {
        typedef typename backend::value_type<Matrix>::type Val;
        typedef ptrdiff_t Idx;

        AMGCL_TIC("aggregates");
        Aggregates aggr(A, prm.aggr, prm.nullspace.cols);
        prm.aggr.eps_strong *= 0.5;
        AMGCL_TOC("aggregates");

        AMGCL_TIC("interpolation");
        auto P_tent = tentative_prolongation<Matrix>(
                rows(A), aggr.count, aggr.id, prm.nullspace, prm.aggr.block_size
                );

        // Filter the system matrix
        backend::crs<Val> Af;
        Af.set_size(rows(A), cols(A));
        Af.ptr[0] = 0;

        std::vector<Val> dia(Af.nrows);

#pragma omp parallel for
        for(Idx i = 0; i < static_cast<Idx>(Af.nrows); ++i) {
            Idx row_begin = A.ptr[i];
            Idx row_end   = A.ptr[i+1];
            Idx row_width = row_end - row_begin;

            Val D = math::zero<Val>();
            for(Idx j = row_begin; j < row_end; ++j) {
                Idx c = A.col[j];
                Val v = A.val[j];

                if (c == i)
                    D += v;
                else if (!aggr.strong_connection[j]) {
                    D += v;
                    --row_width;
                }
            }

            dia[i] = D;
            Af.ptr[i+1] = row_width;
        }

        Af.set_nonzeros(Af.scan_row_sizes());

#pragma omp parallel for
        for(Idx i = 0; i < static_cast<Idx>(Af.nrows); ++i) {
            Idx row_begin = A.ptr[i];
            Idx row_end   = A.ptr[i+1];
            Idx row_head  = Af.ptr[i];

            for(Idx j = row_begin; j < row_end; ++j) {
                Idx c = A.col[j];

                if (c == i) {
                    Af.col[row_head] = i;
                    Af.val[row_head] = dia[i];
                    ++row_head;
                } else if (aggr.strong_connection[j]) {
                    Af.col[row_head] = c;
                    Af.val[row_head] = A.val[j];
                    ++row_head;
                }
            }
        }

        std::vector<Val> omega;

        auto P = interpolation(Af, dia, *P_tent, omega);
        auto R = restriction  (Af, dia, *P_tent, omega);
        AMGCL_TOC("interpolation");

        if (prm.nullspace.cols > 0)
            prm.aggr.block_size = prm.nullspace.cols;

        return std::make_tuple(P, R);
    }
Ejemplo n.º 6
0
void *aggr_combiner (iterator_t *itr)
{
	return aggr(itr);
}
Ejemplo n.º 7
0
    static boost::tuple< boost::shared_ptr<Matrix>, boost::shared_ptr<Matrix> >
    transfer_operators(const Matrix &A, params &prm)
    {
        typedef typename backend::value_type<Matrix>::type value_type;
        typedef typename math::scalar_of<value_type>::type scalar_type;

        const size_t n = rows(A);

        BOOST_AUTO(Aptr, A.ptr_data());
        BOOST_AUTO(Acol, A.col_data());
        BOOST_AUTO(Aval, A.val_data());

        TIC("aggregates");
        Aggregates aggr(A, prm.aggr, prm.nullspace.cols);
        prm.aggr.eps_strong *= 0.5;
        TOC("aggregates");

        TIC("interpolation");
        boost::shared_ptr<Matrix> P_tent = tentative_prolongation<Matrix>(
                n, aggr.count, aggr.id, prm.nullspace, prm.aggr.block_size
                );

        boost::shared_ptr<Matrix> P = boost::make_shared<Matrix>();
        P->nrows = rows(*P_tent);
        P->ncols = cols(*P_tent);

        P->ptr.resize(n + 1, 0);

#pragma omp parallel
        {
            std::vector<ptrdiff_t> marker(P->ncols, -1);

#ifdef _OPENMP
            int nt  = omp_get_num_threads();
            int tid = omp_get_thread_num();

            ptrdiff_t chunk_size  = (n + nt - 1) / nt;
            ptrdiff_t chunk_start = tid * chunk_size;
            ptrdiff_t chunk_end   = std::min<ptrdiff_t>(n, chunk_start + chunk_size);
#else
            ptrdiff_t chunk_start = 0;
            ptrdiff_t chunk_end   = n;
#endif

            // Count number of entries in P.
            for(ptrdiff_t i = chunk_start; i < chunk_end; ++i) {
                for(ptrdiff_t ja = Aptr[i], ea = Aptr[i+1]; ja < ea; ++ja) {
                    ptrdiff_t ca = Acol[ja];

                    // Skip weak off-diagonal connections.
                    if (ca != i && !aggr.strong_connection[ja])
                        continue;

                    for(ptrdiff_t jp = P_tent->ptr[ca], ep = P_tent->ptr[ca+1]; jp < ep; ++jp) {
                        ptrdiff_t cp = P_tent->col[jp];

                        if (marker[cp] != i) {
                            marker[cp] = i;
                            ++( P->ptr[i + 1] );
                        }
                    }
                }
            }

            boost::fill(marker, -1);

#pragma omp barrier
#pragma omp single
            {
                boost::partial_sum(P->ptr, P->ptr.begin());
                P->col.resize(P->ptr.back());
                P->val.resize(P->ptr.back());
            }

            // Fill the interpolation matrix.
            for(ptrdiff_t i = chunk_start; i < chunk_end; ++i) {

                // Diagonal of the filtered matrix is the original matrix
                // diagonal minus its weak connections.
                value_type dia = math::zero<value_type>();
                for(ptrdiff_t j = Aptr[i], e = Aptr[i+1]; j < e; ++j) {
                    if (Acol[j] == i)
                        dia += Aval[j];
                    else if (!aggr.strong_connection[j])
                        dia -= Aval[j];
                }
                dia = math::inverse(dia);

                ptrdiff_t row_beg = P->ptr[i];
                ptrdiff_t row_end = row_beg;
                for(ptrdiff_t ja = Aptr[i], ea = Aptr[i + 1]; ja < ea; ++ja) {
                    ptrdiff_t ca = Acol[ja];

                    // Skip weak off-diagonal connections.
                    if (ca != i && !aggr.strong_connection[ja]) continue;

                    value_type va = (ca == i)
                        ? static_cast<value_type>(static_cast<scalar_type>(1 - prm.relax) * math::identity<value_type>())
                        : static_cast<value_type>(static_cast<scalar_type>(-prm.relax) * dia * Aval[ja]);

                    for(ptrdiff_t jp = P_tent->ptr[ca], ep = P_tent->ptr[ca+1]; jp < ep; ++jp) {
                        ptrdiff_t cp = P_tent->col[jp];
                        value_type vp = P_tent->val[jp];

                        if (marker[cp] < row_beg) {
                            marker[cp] = row_end;
                            P->col[row_end] = cp;
                            P->val[row_end] = va * vp;
                            ++row_end;
                        } else {
                            P->val[ marker[cp] ] += va * vp;
                        }
                    }
                }
            }
        }
        TOC("interpolation");

        boost::shared_ptr<Matrix> R = boost::make_shared<Matrix>();
        *R = transpose(*P);

        if (prm.nullspace.cols > 0)
            prm.aggr.block_size = prm.nullspace.cols;

        return boost::make_tuple(P, R);
    }
Ejemplo n.º 8
0
    static boost::tuple< boost::shared_ptr<Matrix>, boost::shared_ptr<Matrix> >
    transfer_operators(const Matrix &A, params &prm)
    {
        typedef typename backend::value_type<Matrix>::type Val;

        const size_t n = rows(A);

        TIC("aggregates");
        Aggregates aggr(A, prm.aggr);
        prm.aggr.eps_strong *= 0.5;
        TOC("aggregates");

        TIC("interpolation");
        boost::shared_ptr<Matrix> P = boost::make_shared<Matrix>();
        P->nrows = n;
        P->ncols = aggr.count;
        P->ptr.resize(n + 1, 0);

#pragma omp parallel
        {
            std::vector<ptrdiff_t> marker(aggr.count, -1);

#ifdef _OPENMP
            int nt  = omp_get_num_threads();
            int tid = omp_get_thread_num();

            size_t chunk_size  = (n + nt - 1) / nt;
            size_t chunk_start = tid * chunk_size;
            size_t chunk_end   = std::min(n, chunk_start + chunk_size);
#else
            size_t chunk_start = 0;
            size_t chunk_end   = n;
#endif

            // Count number of entries in P.
            for(size_t i = chunk_start; i < chunk_end; ++i) {
                for(ptrdiff_t j = A.ptr[i], e = A.ptr[i+1]; j < e; ++j) {
                    size_t c = static_cast<size_t>(A.col[j]);

                    // Skip weak off-diagonal connections.
                    if (c != i && !aggr.strong_connection[j])
                        continue;

                    ptrdiff_t g = aggr.id[c];

                    if (g >= 0 && static_cast<size_t>(marker[g]) != i) {
                        marker[g] = static_cast<ptrdiff_t>(i);
                        ++( P->ptr[i + 1] );
                    }
                }
            }

            boost::fill(marker, -1);

#pragma omp barrier
#pragma omp single
            {
                boost::partial_sum(P->ptr, P->ptr.begin());
                P->col.resize(P->ptr.back());
                P->val.resize(P->ptr.back());
            }

            // Fill the interpolation matrix.
            for(size_t i = chunk_start; i < chunk_end; ++i) {

                // Diagonal of the filtered matrix is the original matrix
                // diagonal minus its weak connections.
                Val dia = 0;
                for(ptrdiff_t j = A.ptr[i], e = A.ptr[i+1]; j < e; ++j) {
                    if (static_cast<size_t>(A.col[j]) == i)
                        dia += A.val[j];
                    else if (!aggr.strong_connection[j])
                        dia -= A.val[j];
                }
                dia = 1 / dia;

                ptrdiff_t row_beg = P->ptr[i];
                ptrdiff_t row_end = row_beg;
                for(ptrdiff_t j = A.ptr[i], e = A.ptr[i + 1]; j < e; ++j) {
                    size_t c = static_cast<size_t>(A.col[j]);

                    // Skip weak couplings, ...
                    if (c != i && !aggr.strong_connection[j]) continue;

                    // ... and the ones not in any aggregate.
                    ptrdiff_t g = aggr.id[c];
                    if (g < 0) continue;

                    Val v = (c == i) ? 1 - prm.relax : -prm.relax * dia * A.val[j];

                    if (marker[g] < row_beg) {
                        marker[g] = row_end;
                        P->col[row_end] = g;
                        P->val[row_end] = v;
                        ++row_end;
                    } else {
                        P->val[ marker[g] ] += v;
                    }
                }
            }
        }
        TOC("interpolation");

        boost::shared_ptr<Matrix> R = boost::make_shared<Matrix>();
        *R = transpose(*P);

        return boost::make_tuple(P, R);
    }
Ejemplo n.º 9
0
        pointwise_aggregates(const Matrix &A, const params &prm, unsigned min_aggregate)
            : count(0)
        {
            typedef typename backend::value_type<Matrix>::type value_type;
            typedef typename math::scalar_of<value_type>::type scalar_type;
            if (prm.block_size == 1) {
                plain_aggregates aggr(A, prm);

                remove_small_aggregates(A.nrows, 1, min_aggregate, aggr);

                count = aggr.count;
                strong_connection.swap(aggr.strong_connection);
                id.swap(aggr.id);
            } else {
                strong_connection.resize( nonzeros(A) );
                id.resize( rows(A) );

                auto ap = backend::pointwise_matrix(A, prm.block_size);
                backend::crs<scalar_type> &Ap = *ap;

                plain_aggregates pw_aggr(Ap, prm);

                remove_small_aggregates(
                        Ap.nrows, prm.block_size, min_aggregate, pw_aggr);

                count = pw_aggr.count * prm.block_size;

#pragma omp parallel
                {
                    std::vector<ptrdiff_t> j(prm.block_size);
                    std::vector<ptrdiff_t> e(prm.block_size);

#pragma omp for
                    for(ptrdiff_t ip = 0; ip < static_cast<ptrdiff_t>(Ap.nrows); ++ip) {
                        ptrdiff_t ia = ip * prm.block_size;

                        for(unsigned k = 0; k < prm.block_size; ++k, ++ia) {
                            id[ia] = prm.block_size * pw_aggr.id[ip] + k;

                            j[k] = A.ptr[ia];
                            e[k] = A.ptr[ia+1];
                        }

                        for(ptrdiff_t jp = Ap.ptr[ip], ep = Ap.ptr[ip+1]; jp < ep; ++jp) {
                            ptrdiff_t cp = Ap.col[jp];
                            bool      sp = (cp == ip) || pw_aggr.strong_connection[jp];

                            ptrdiff_t col_end = (cp + 1) * prm.block_size;

                            for(unsigned k = 0; k < prm.block_size; ++k) {
                                ptrdiff_t beg = j[k];
                                ptrdiff_t end = e[k];

                                while(beg < end && A.col[beg] < col_end) {
                                    strong_connection[beg] = sp && A.col[beg] != (ia + k);
                                    ++beg;
                                }

                                j[k] = beg;
                            }
                        }
                    }
                }
            }
        }