<commit_before>## async.py
# Light wrapper around whatever async library pydle uses.
import functools
import itertools
import collections
import threading
import datetime
import types

import tornado.concurrent
import tornado.ioloop

FUTURE_TIMEOUT = 30

class Future(tornado.concurrent.TracebackFuture):
    """
    A future. An object that represents a result that has yet to be created or returned.
    """

def coroutine(func):
    """ Decorator for coroutine functions that need to block for asynchronous operations. """
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        return_future = Future()

        def handle_future(future):
            # Chained futures!
            try:
                if future.exception() is not None:
                    result = gen.throw(future.exception())
                else:
                    result = gen.send(future.result())
                if isinstance(result, tuple):
                    result = parallel(*result)
                result.add_done_callback(handle_future)
            except StopIteration as e:
                return_future.set_result(getattr(e, 'value', None))
            except Exception as e:
                return_future.set_exception(e)

        try:
            # Handle initial value.
            gen = func(*args, **kwargs)
        except Exception as e:
            return_future.set_exception(e)
            return return_future
        else:
            # If this isn't a generator, then wrap the result with a future.
            if not isinstance(gen, types.GeneratorType):
                return_future.set_result(gen)
                return return_future

        try:
            result = next(gen)
            if isinstance(result, tuple):
                result = parallel(*result)
            result.add_done_callback(handle_future)
        except StopIteration as e:
            return_future.set_result(getattr(e, 'value', None))
        except Exception as e:
            return_future.set_exception(e)

        return return_future
    return wrapper

def parallel(*futures):
    """ Create a single future that will be completed when all the given futures are. """
    result_future = Future()
    results = collections.OrderedDict(zip(futures, itertools.repeat(None)))
    futures = list(futures)

    if not futures:
        # If we don't have any futures, then we return an empty tuple.
        result_future.set_result(())
        return result_future

    def done(future):
        futures.remove(future)
        results[future] = future.result()
        # All out of futures. set the result.
        if not futures:
            result_future.set_result(tuple(results.values()))

    for future in futures:
        future.add_done_callback(done)

    return result_future

class EventLoop:
    """ A light wrapper around what event loop mechanism pydle uses underneath. """
    EVENT_MAPPING = {
        'read': tornado.ioloop.IOLoop.READ,
        'write': tornado.ioloop.IOLoop.WRITE,
        'error': tornado.ioloop.IOLoop.ERROR
    }

    def __init__(self, io_loop=None):
        self.io_loop = io_loop or tornado.ioloop.IOLoop.current()
        self.running = False
        self.run_thread = None
        self.handlers = {}
        self.future_timeout = FUTURE_TIMEOUT
        self._registered_events = False
        self._future_timeouts = {}
        self._timeout_id = 0
        self._timeout_handles = {}

    def __del__(self):
        self.io_loop.close()

    def register(self, fd):
        """ Register a file descriptor with this event loop. """
        self.handlers[fd] = { key: [] for key in self.EVENT_MAPPING }

    def unregister(self, fd):
        """ Unregister a file descriptor with this event loop. """
        del self.handlers[fd]

    def on_read(self, fd, callback):
        """
        Add a callback for when the given file descriptor is available for reading.
        Callback will be called with file descriptor as sole argument.
        """
        self.handlers[fd]['read'].append(callback)
        self._update_events(fd)

    def on_write(self, fd, callback):
        """
        Add a callback for when the given file descriptor is available for writing.
        Callback will be called with file descriptor as sole argument.
        """
        self.handlers[fd]['write'].append(callback)
        self._update_events(fd)

    def on_error(self, fd, callback):
        """
        Add a callback for when an error has occurred on the given file descriptor.
        Callback will be called with file descriptor as sole argument.
        """
        self.handlers[fd]['error'].append(callback)
        self._update_events(fd)

    def off_read(self, fd, callback):
        """ Remove read callback for given file descriptor. """
        self.handlers[fd]['read'].remove(callback)
        self._update_events(fd)

    def off_write(self, fd, callback):
        """ Remove write callback for given file descriptor. """
        self.handlers[fd]['write'].remove(callback)
        self._update_events(fd)

    def off_error(self, fd, callback):
        """ Remove error callback for given file descriptor. """
        self.handlers[fd]['error'].remove(callback)
        self._update_events(fd)

    def handles_read(self, fd, callback):
        """ Return whether or the given read callback is active for the given file descriptor. """
        return callback in self.handlers[fd]['read']

    def handles_write(self, fd, callback):
        """ Return whether or the given write callback is active for the given file descriptor. """
        return callback in self.handlers[fd]['write']

    def handles_error(self, fd, callback):
        """ Return whether or the given error callback is active for the given file descriptor. """
        return callback in self.handlers[fd]['error']

    def _update_events(self, fd):
        if self._registered_events:
            self.io_loop.remove_handler(fd)

        events = 0
        for event, ident in self.EVENT_MAPPING.items():
            if self.handlers[fd][event]:
                events |= ident

        self.io_loop.add_handler(fd, self._do_on_event, events)
        self._registered_events = True

    def _do_on_event(self, fd, events):
        if fd not in self.handlers:
            return

        for event, ident in self.EVENT_MAPPING.items():
            if events & ident:
                for handler in self.handlers[fd][event]:
                    handler(fd)

    def on_future(self, _future, _callback, *_args, **_kwargs):
        """ Add a callback for when the given future has been resolved. """
        callback = functools.partial(self._do_on_future, _callback, _args, _kwargs)

        # Create timeout handler and regular handler.
        self._future_timeouts[_future] = self.schedule_in(self.future_timeout, callback)
        self.io_loop.add_future(_future, callback)

    def _do_on_future(self, callback, args, kwargs, future):
        # This was a time-out.
        if not future.done():
            future.set_exception(TimeoutError('Future timed out before yielding a result.'))
            del self._future_timeouts[future]
        # This was a time-out that already has been handled.
        elif isinstance(future.exception(), TimeoutError):
            return
        # A regular result. Cancel the timeout.
        else:
            self.unschedule(self._future_timeouts.pop(future))

        # Call callback.
        callback(*args, **kwargs)

    def _get_schedule_handle(self):
        """ Get a unique handle for use in the schedule_* functions. """
        # Just use a simple monotonically increasing number.
        handle = self._timeout_id
        self._timeout_id += 1

        return handle

    def schedule(self, _callback, *_args, **_kwargs):
        """ Schedule a callback to be ran as soon as possible in this loop. """
        self.io_loop.add_callback(_callback, *_args, **_kwargs)

    def schedule_in(self, _when, _callback, *_args, **_kwargs):
        """
        Schedule a callback to be ran as soon as possible after `when` seconds have passed.
        Will return an opaque handle that can be passed to `unschedule` to unschedule the function.
        """
        if not isinstance(_when, datetime.timedelta):
            _when = datetime.timedelta(seconds=_when)

        # Create ID for this timeout.
        id = self._get_schedule_handle()

        if self.run_thread != threading.current_thread().ident:
            # Schedule scheduling in IOLoop thread because of thread-safety.
            self.schedule(functools.partial(self._do_schedule_in, id, _when, _callback, _args, _kwargs))
        else:
            self._do_schedule_in(id, _when, _callback, _args, _kwargs)

        return id

    def schedule_periodically(self, _interval, _callback, *_args, **_kwargs):
        """
        Schedule a callback to be ran every `interval` seconds.
        Will return an opaque handle that can be passed to unschedule() to unschedule the interval function.
        A function will also stop being scheduled if it returns False or raises an Exception.
        """
        if not isinstance(_interval, datetime.timedelta):
            _interval = datetime.timedelta(seconds=_interval)

        # Create ID for this periodic.
        id = self._get_schedule_handle()

        if self.run_thread != threading.current_thread().ident:
            # Schedule scheduling in IOLoop thread because of thread-safety.
            self.schedule(functools.partial(self._do_schedule_periodically, id, _interval, _callback, _args, _kwargs))
        else:
            self._do_schedule_periodically(id, _interval, _callback, _args, _kwargs)

        return id

    def _do_schedule_in(self, id, when, callback, args, kwargs):
        self._timeout_handles[id] = self.io_loop.add_timeout(when, functools.partial(callback, *args, **kwargs))

    def _do_schedule_periodically(self, id, interval, callback, args, kwargs):
        # Use a wrapper function.
        self._timeout_handles[id] = self.io_loop.add_timeout(interval, functools.partial(self._periodic_handler, id, interval, callback, args, kwargs))

    def _periodic_handler(self, id, interval, callback, args, kwargs):
        # We could've been unscheduled for some reason.
        if not self.is_scheduled(id):
            return

        # Call callback, and schedule again if it doesn't return False.
        self._do_schedule_periodically(id, interval, callback, args, kwargs)
        result = False

        try:
            result = callback(*args, **kwargs)
        finally:
            if result == False:
                self.unschedule(id)

    def is_scheduled(self, handle):
        """ Return whether or not the given handle is still scheduled. """
        return handle in self._timeout_handles

    def unschedule(self, handle):
        """ Unschedule a given timeout or periodical callback. """
        if self.is_scheduled(handle):
            handle = self._timeout_handles.pop(handle)
            self.io_loop.remove_timeout(handle)

    def run(self):
        """ Run the event loop. """
        if not self.running:
            self.running = True
            self.run_thread = threading.current_thread().ident
            self.io_loop.start()
            self.run_thread = None
            self.running = False

    def run_with(self, func):
        """ Run loop, call function, stop loop. If function returns a future, run until the future has been resolved. """
        self.running = True
        self.run_thread = threading.current_thread().ident
        self.io_loop.run_sync(func)
        self.run_thread = None
        self.running = False

    def run_until(self, future):
        """ Run until future is resolved. """
        return self.run_with(lambda: future)

    def stop(self):
        """ Stop the event loop. """
        if self.running:
            self.io_loop.stop()
<commit_msg>Properly show exceptions in coroutines.<commit_after>## async.py
# Light wrapper around whatever async library pydle uses.
import functools
import itertools
import collections
import threading
import datetime
import types

import tornado.concurrent
import tornado.ioloop

FUTURE_TIMEOUT = 30

class Future(tornado.concurrent.TracebackFuture):
    """
    A future. An object that represents a result that has yet to be created or returned.
    """

def coroutine(func):
    """ Decorator for coroutine functions that need to block for asynchronous operations. """
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        return_future = Future()

        def handle_future(future):
            # Chained futures!
            try:
                if future.exception() is not None:
                    result = gen.throw(future.exception())
                else:
                    result = gen.send(future.result())
                if isinstance(result, tuple):
                    result = parallel(*result)
                result.add_done_callback(handle_future)
            except StopIteration as e:
                return_future.set_result(getattr(e, 'value', None))

        # Handle initial value.
        gen = func(*args, **kwargs)

        # If this isn't a generator, then wrap the result with a future.
        if not isinstance(gen, types.GeneratorType):
            return_future.set_result(gen)
            return return_future

        try:
            result = next(gen)
            if isinstance(result, tuple):
                result = parallel(*result)
            result.add_done_callback(handle_future)
        except StopIteration as e:
            return_future.set_result(getattr(e, 'value', None))

        return return_future
    return wrapper

def parallel(*futures):
    """ Create a single future that will be completed when all the given futures are. """
    result_future = Future()
    results = collections.OrderedDict(zip(futures, itertools.repeat(None)))
    futures = list(futures)

    if not futures:
        # If we don't have any futures, then we return an empty tuple.
        result_future.set_result(())
        return result_future

    def done(future):
        futures.remove(future)
        results[future] = future.result()
        # All out of futures. set the result.
        if not futures:
            result_future.set_result(tuple(results.values()))

    for future in futures:
        future.add_done_callback(done)

    return result_future

class EventLoop:
    """ A light wrapper around what event loop mechanism pydle uses underneath. """
    EVENT_MAPPING = {
        'read': tornado.ioloop.IOLoop.READ,
        'write': tornado.ioloop.IOLoop.WRITE,
        'error': tornado.ioloop.IOLoop.ERROR
    }

    def __init__(self, io_loop=None):
        self.io_loop = io_loop or tornado.ioloop.IOLoop.current()
        self.running = False
        self.run_thread = None
        self.handlers = {}
        self.future_timeout = FUTURE_TIMEOUT
        self._registered_events = False
        self._future_timeouts = {}
        self._timeout_id = 0
        self._timeout_handles = {}

    def __del__(self):
        self.io_loop.close()

    def register(self, fd):
        """ Register a file descriptor with this event loop. """
        self.handlers[fd] = { key: [] for key in self.EVENT_MAPPING }

    def unregister(self, fd):
        """ Unregister a file descriptor with this event loop. """
        del self.handlers[fd]

    def on_read(self, fd, callback):
        """
        Add a callback for when the given file descriptor is available for reading.
        Callback will be called with file descriptor as sole argument.
        """
        self.handlers[fd]['read'].append(callback)
        self._update_events(fd)

    def on_write(self, fd, callback):
        """
        Add a callback for when the given file descriptor is available for writing.
        Callback will be called with file descriptor as sole argument.
        """
        self.handlers[fd]['write'].append(callback)
        self._update_events(fd)

    def on_error(self, fd, callback):
        """
        Add a callback for when an error has occurred on the given file descriptor.
        Callback will be called with file descriptor as sole argument.
        """
        self.handlers[fd]['error'].append(callback)
        self._update_events(fd)

    def off_read(self, fd, callback):
        """ Remove read callback for given file descriptor. """
        self.handlers[fd]['read'].remove(callback)
        self._update_events(fd)

    def off_write(self, fd, callback):
        """ Remove write callback for given file descriptor. """
        self.handlers[fd]['write'].remove(callback)
        self._update_events(fd)

    def off_error(self, fd, callback):
        """ Remove error callback for given file descriptor. """
        self.handlers[fd]['error'].remove(callback)
        self._update_events(fd)

    def handles_read(self, fd, callback):
        """ Return whether or the given read callback is active for the given file descriptor. """
        return callback in self.handlers[fd]['read']

    def handles_write(self, fd, callback):
        """ Return whether or the given write callback is active for the given file descriptor. """
        return callback in self.handlers[fd]['write']

    def handles_error(self, fd, callback):
        """ Return whether or the given error callback is active for the given file descriptor. """
        return callback in self.handlers[fd]['error']

    def _update_events(self, fd):
        if self._registered_events:
            self.io_loop.remove_handler(fd)

        events = 0
        for event, ident in self.EVENT_MAPPING.items():
            if self.handlers[fd][event]:
                events |= ident

        self.io_loop.add_handler(fd, self._do_on_event, events)
        self._registered_events = True

    def _do_on_event(self, fd, events):
        if fd not in self.handlers:
            return

        for event, ident in self.EVENT_MAPPING.items():
            if events & ident:
                for handler in self.handlers[fd][event]:
                    handler(fd)

    def on_future(self, _future, _callback, *_args, **_kwargs):
        """ Add a callback for when the given future has been resolved. """
        callback = functools.partial(self._do_on_future, _callback, _args, _kwargs)

        # Create timeout handler and regular handler.
        self._future_timeouts[_future] = self.schedule_in(self.future_timeout, callback)
        self.io_loop.add_future(_future, callback)

    def _do_on_future(self, callback, args, kwargs, future):
        # This was a time-out.
        if not future.done():
            future.set_exception(TimeoutError('Future timed out before yielding a result.'))
            del self._future_timeouts[future]
        # This was a time-out that already has been handled.
        elif isinstance(future.exception(), TimeoutError):
            return
        # A regular result. Cancel the timeout.
        else:
            self.unschedule(self._future_timeouts.pop(future))

        # Call callback.
        callback(*args, **kwargs)

    def _get_schedule_handle(self):
        """ Get a unique handle for use in the schedule_* functions. """
        # Just use a simple monotonically increasing number.
        handle = self._timeout_id
        self._timeout_id += 1

        return handle

    def schedule(self, _callback, *_args, **_kwargs):
        """ Schedule a callback to be ran as soon as possible in this loop. """
        self.io_loop.add_callback(_callback, *_args, **_kwargs)

    def schedule_in(self, _when, _callback, *_args, **_kwargs):
        """
        Schedule a callback to be ran as soon as possible after `when` seconds have passed.
        Will return an opaque handle that can be passed to `unschedule` to unschedule the function.
        """
        if not isinstance(_when, datetime.timedelta):
            _when = datetime.timedelta(seconds=_when)

        # Create ID for this timeout.
        id = self._get_schedule_handle()

        if self.run_thread != threading.current_thread().ident:
            # Schedule scheduling in IOLoop thread because of thread-safety.
            self.schedule(functools.partial(self._do_schedule_in, id, _when, _callback, _args, _kwargs))
        else:
            self._do_schedule_in(id, _when, _callback, _args, _kwargs)

        return id

    def schedule_periodically(self, _interval, _callback, *_args, **_kwargs):
        """
        Schedule a callback to be ran every `interval` seconds.
        Will return an opaque handle that can be passed to unschedule() to unschedule the interval function.
        A function will also stop being scheduled if it returns False or raises an Exception.
        """
        if not isinstance(_interval, datetime.timedelta):
            _interval = datetime.timedelta(seconds=_interval)

        # Create ID for this periodic.
        id = self._get_schedule_handle()

        if self.run_thread != threading.current_thread().ident:
            # Schedule scheduling in IOLoop thread because of thread-safety.
            self.schedule(functools.partial(self._do_schedule_periodically, id, _interval, _callback, _args, _kwargs))
        else:
            self._do_schedule_periodically(id, _interval, _callback, _args, _kwargs)

        return id

    def _do_schedule_in(self, id, when, callback, args, kwargs):
        self._timeout_handles[id] = self.io_loop.add_timeout(when, functools.partial(callback, *args, **kwargs))

    def _do_schedule_periodically(self, id, interval, callback, args, kwargs):
        # Use a wrapper function.
        self._timeout_handles[id] = self.io_loop.add_timeout(interval, functools.partial(self._periodic_handler, id, interval, callback, args, kwargs))

    def _periodic_handler(self, id, interval, callback, args, kwargs):
        # We could've been unscheduled for some reason.
        if not self.is_scheduled(id):
            return

        # Call callback, and schedule again if it doesn't return False.
        self._do_schedule_periodically(id, interval, callback, args, kwargs)
        result = False

        try:
            result = callback(*args, **kwargs)
        finally:
            if result == False:
                self.unschedule(id)

    def is_scheduled(self, handle):
        """ Return whether or not the given handle is still scheduled. """
        return handle in self._timeout_handles

    def unschedule(self, handle):
        """ Unschedule a given timeout or periodical callback. """
        if self.is_scheduled(handle):
            handle = self._timeout_handles.pop(handle)
            self.io_loop.remove_timeout(handle)

    def run(self):
        """ Run the event loop. """
        if not self.running:
            self.running = True
            self.run_thread = threading.current_thread().ident
            self.io_loop.start()
            self.run_thread = None
            self.running = False

    def run_with(self, func):
        """ Run loop, call function, stop loop. If function returns a future, run until the future has been resolved. """
        self.running = True
        self.run_thread = threading.current_thread().ident
        self.io_loop.run_sync(func)
        self.run_thread = None
        self.running = False

    def run_until(self, future):
        """ Run until future is resolved. """
        return self.run_with(lambda: future)

    def stop(self):
        """ Stop the event loop. """
        if self.running:
            self.io_loop.stop()
<|endoftext|>


<commit_before>roman_numeral_map = (('M', 1000),
                     ('CM', 900),
                     ('D', 500),
                     ('CD', 400),
                     ('C', 100),
                     ('XC', 90),
                     ('L', 50),
                     ('XL', 40),
                     ('X', 10),
                     ('IX', 9),
                     ('V',  5),
                     ('IV', 4),
                     ('I', 1))

def to_roman(n):
    '''Take an integer between 1 and 3999 and return Roman numeral
    '''
    result = ''
    for numeral, integer in roman_numeral_map:
        while n >= integer:
            result += numeral
            n -= integer
    return result
<commit_msg>Add input checking for to_roman. Stub from_roman.<commit_after>class OutOfRangeError(ValueError):
    pass

class NotIntegerError(ValueError):
    pass

roman_numeral_map = (('M', 1000),
                     ('CM', 900),
                     ('D', 500),
                     ('CD', 400),
                     ('C', 100),
                     ('XC', 90),
                     ('L', 50),
                     ('XL', 40),
                     ('X', 10),
                     ('IX', 9),
                     ('V',  5),
                     ('IV', 4),
                     ('I', 1))

def to_roman(n):
    '''Take an integer between 1 and 3999 and return Roman numeral
    '''
    if not isinstance(n, int):
        raise NotIntegerError(
            'Input is not of integer type.')
    if n >= 4000 or n <= 0:
        raise OutOfRangeError(
            'Number out of range (must be betwen 1 and 3999 inclusive).')
    result = ''
    for numeral, integer in roman_numeral_map:
        while n >= integer:
            result += numeral
            n -= integer
    return result

def from_roman(s):
    pass
<|endoftext|>


<commit_before>import numpy

# PyCUDA libraries
try:
    import pycuda.autoinit
    import pycuda.gpuarray as gpuarray
    import pycuda.driver as cuda
except:
    pass

from classes import Event

def dataTransfer(surf_array, field_array, ind, param, kernel):
    '''
    It manages the data transfer to the GPU.

    Arguments:
    ----------
    surf_array :
    field_array:
    ind        :
    param      :
    kernel     :

    '''

    REAL = param.REAL
    Nsurf = len(surf_array)
    for s in range(Nsurf):
        surf_array[s].xiDev = gpuarray.to_gpu(surf_array[s].xiSort.astype(
            REAL))
        surf_array[s].yiDev = gpuarray.to_gpu(surf_array[s].yiSort.astype(
            REAL))
        surf_array[s].ziDev = gpuarray.to_gpu(surf_array[s].ziSort.astype(
            REAL))
        surf_array[s].xjDev = gpuarray.to_gpu(surf_array[s].xjSort.astype(
            REAL))
        surf_array[s].yjDev = gpuarray.to_gpu(surf_array[s].yjSort.astype(
            REAL))
        surf_array[s].zjDev = gpuarray.to_gpu(surf_array[s].zjSort.astype(
            REAL))
        surf_array[s].AreaDev = gpuarray.to_gpu(surf_array[s].AreaSort.astype(
            REAL))
        surf_array[s].sglInt_intDev = gpuarray.to_gpu(surf_array[
            s].sglInt_intSort.astype(REAL))
        surf_array[s].sglInt_extDev = gpuarray.to_gpu(surf_array[
            s].sglInt_extSort.astype(REAL))
        surf_array[s].vertexDev = gpuarray.to_gpu(numpy.ravel(surf_array[
            s].vertex[surf_array[s].triangleSort]).astype(REAL))
        surf_array[s].xcDev = gpuarray.to_gpu(numpy.ravel(surf_array[
            s].xcSort.astype(REAL)))
        surf_array[s].ycDev = gpuarray.to_gpu(numpy.ravel(surf_array[
            s].ycSort.astype(REAL)))
        surf_array[s].zcDev = gpuarray.to_gpu(numpy.ravel(surf_array[
            s].zcSort.astype(REAL)))

        #       Avoid transferring size 1 arrays to GPU (some systems crash)
        Nbuff = 5
        if len(surf_array[s].sizeTarget) < Nbuff:
            sizeTarget_buffer = numpy.zeros(Nbuff, dtype=numpy.int32)
            sizeTarget_buffer[:len(surf_array[s].sizeTarget)] = surf_array[
                s].sizeTarget[:]
            surf_array[s].sizeTarDev = gpuarray.to_gpu(sizeTarget_buffer)
        else:
            surf_array[s].sizeTarDev = gpuarray.to_gpu(surf_array[
                s].sizeTarget.astype(numpy.int32))

    #        surf_array[s].sizeTarDev = gpuarray.to_gpu(surf_array[s].sizeTarget.astype(numpy.int32))
        surf_array[s].offSrcDev = gpuarray.to_gpu(surf_array[
            s].offsetSource.astype(numpy.int32))
        surf_array[s].offTwgDev = gpuarray.to_gpu(numpy.ravel(surf_array[
            s].offsetTwigs.astype(numpy.int32)))
        surf_array[s].offMltDev = gpuarray.to_gpu(numpy.ravel(surf_array[
            s].offsetMlt.astype(numpy.int32)))
        surf_array[s].M2P_lstDev = gpuarray.to_gpu(numpy.ravel(surf_array[
            s].M2P_list.astype(numpy.int32)))
        surf_array[s].P2P_lstDev = gpuarray.to_gpu(numpy.ravel(surf_array[
            s].P2P_list.astype(numpy.int32)))
        surf_array[s].xkDev = gpuarray.to_gpu(surf_array[s].xk.astype(REAL))
        surf_array[s].wkDev = gpuarray.to_gpu(surf_array[s].wk.astype(REAL))
        surf_array[s].XskDev = gpuarray.to_gpu(surf_array[s].Xsk.astype(REAL))
        surf_array[s].WskDev = gpuarray.to_gpu(surf_array[s].Wsk.astype(REAL))
        surf_array[s].kDev = gpuarray.to_gpu((surf_array[s].sortSource %
                                              param.K).astype(numpy.int32))

    ind.indexDev = gpuarray.to_gpu(ind.index_large.astype(numpy.int32))

    Nfield = len(field_array)
    for f in range(Nfield):
        if len(field_array[f].xq) > 0:
            field_array[f].xq_gpu = gpuarray.to_gpu(field_array[
                f].xq[:, 0].astype(REAL))
            field_array[f].yq_gpu = gpuarray.to_gpu(field_array[
                f].xq[:, 1].astype(REAL))
            field_array[f].zq_gpu = gpuarray.to_gpu(field_array[
                f].xq[:, 2].astype(REAL))
            field_array[f].q_gpu = gpuarray.to_gpu(field_array[f].q.astype(
                REAL))
<commit_msg>gpuio.py documented<commit_after>"""
It contains the function in charge of the data transfer to the GPU.
"""
import numpy

# PyCUDA libraries
try:
    import pycuda.autoinit
    import pycuda.gpuarray as gpuarray
    import pycuda.driver as cuda
except:
    pass

from classes import Event

def dataTransfer(surf_array, field_array, ind, param, kernel):
    '''
    It manages the data transfer to the GPU.

    Arguments:
    ----------
    surf_array : array, contains the surface classes of each region on the
                        surface.
    field_array: array, contains the Field classes of each region on the surface.
    ind        : class, it contains the indices related to the treecode
                        computation.
    param      : class, parameters related to the surface.
    kernel: pycuda source module.

    '''

    REAL = param.REAL
    Nsurf = len(surf_array)
    for s in range(Nsurf):
        surf_array[s].xiDev = gpuarray.to_gpu(surf_array[s].xiSort.astype(
            REAL))
        surf_array[s].yiDev = gpuarray.to_gpu(surf_array[s].yiSort.astype(
            REAL))
        surf_array[s].ziDev = gpuarray.to_gpu(surf_array[s].ziSort.astype(
            REAL))
        surf_array[s].xjDev = gpuarray.to_gpu(surf_array[s].xjSort.astype(
            REAL))
        surf_array[s].yjDev = gpuarray.to_gpu(surf_array[s].yjSort.astype(
            REAL))
        surf_array[s].zjDev = gpuarray.to_gpu(surf_array[s].zjSort.astype(
            REAL))
        surf_array[s].AreaDev = gpuarray.to_gpu(surf_array[s].AreaSort.astype(
            REAL))
        surf_array[s].sglInt_intDev = gpuarray.to_gpu(surf_array[
            s].sglInt_intSort.astype(REAL))
        surf_array[s].sglInt_extDev = gpuarray.to_gpu(surf_array[
            s].sglInt_extSort.astype(REAL))
        surf_array[s].vertexDev = gpuarray.to_gpu(numpy.ravel(surf_array[
            s].vertex[surf_array[s].triangleSort]).astype(REAL))
        surf_array[s].xcDev = gpuarray.to_gpu(numpy.ravel(surf_array[
            s].xcSort.astype(REAL)))
        surf_array[s].ycDev = gpuarray.to_gpu(numpy.ravel(surf_array[
            s].ycSort.astype(REAL)))
        surf_array[s].zcDev = gpuarray.to_gpu(numpy.ravel(surf_array[
            s].zcSort.astype(REAL)))

        #       Avoid transferring size 1 arrays to GPU (some systems crash)
        Nbuff = 5
        if len(surf_array[s].sizeTarget) < Nbuff:
            sizeTarget_buffer = numpy.zeros(Nbuff, dtype=numpy.int32)
            sizeTarget_buffer[:len(surf_array[s].sizeTarget)] = surf_array[
                s].sizeTarget[:]
            surf_array[s].sizeTarDev = gpuarray.to_gpu(sizeTarget_buffer)
        else:
            surf_array[s].sizeTarDev = gpuarray.to_gpu(surf_array[
                s].sizeTarget.astype(numpy.int32))

    #        surf_array[s].sizeTarDev = gpuarray.to_gpu(surf_array[s].sizeTarget.astype(numpy.int32))
        surf_array[s].offSrcDev = gpuarray.to_gpu(surf_array[
            s].offsetSource.astype(numpy.int32))
        surf_array[s].offTwgDev = gpuarray.to_gpu(numpy.ravel(surf_array[
            s].offsetTwigs.astype(numpy.int32)))
        surf_array[s].offMltDev = gpuarray.to_gpu(numpy.ravel(surf_array[
            s].offsetMlt.astype(numpy.int32)))
        surf_array[s].M2P_lstDev = gpuarray.to_gpu(numpy.ravel(surf_array[
            s].M2P_list.astype(numpy.int32)))
        surf_array[s].P2P_lstDev = gpuarray.to_gpu(numpy.ravel(surf_array[
            s].P2P_list.astype(numpy.int32)))
        surf_array[s].xkDev = gpuarray.to_gpu(surf_array[s].xk.astype(REAL))
        surf_array[s].wkDev = gpuarray.to_gpu(surf_array[s].wk.astype(REAL))
        surf_array[s].XskDev = gpuarray.to_gpu(surf_array[s].Xsk.astype(REAL))
        surf_array[s].WskDev = gpuarray.to_gpu(surf_array[s].Wsk.astype(REAL))
        surf_array[s].kDev = gpuarray.to_gpu((surf_array[s].sortSource %
                                              param.K).astype(numpy.int32))

    ind.indexDev = gpuarray.to_gpu(ind.index_large.astype(numpy.int32))

    Nfield = len(field_array)
    for f in range(Nfield):
        if len(field_array[f].xq) > 0:
            field_array[f].xq_gpu = gpuarray.to_gpu(field_array[
                f].xq[:, 0].astype(REAL))
            field_array[f].yq_gpu = gpuarray.to_gpu(field_array[
                f].xq[:, 1].astype(REAL))
            field_array[f].zq_gpu = gpuarray.to_gpu(field_array[
                f].xq[:, 2].astype(REAL))
            field_array[f].q_gpu = gpuarray.to_gpu(field_array[f].q.astype(
                REAL))
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
r"""
This module implements some utilitary functions used throughout the PyGSP box.
"""

import numpy as np
import scipy as sp
from scipy import sparse
from scipy.sparse import linalg
from math import isinf, isnan

import pygsp

def graph_array_handler(func):

    def inner(G, *args, **kwargs):

        if isinstance(G, pygsp.graphs.Graph):
            return func(G, *args, **kwargs)

        elif type(G) is list:
            output = []
            for g in G:
                output.append(func(g, *args, **kwargs))

            return output

        else:
            raise TypeError("This function only accept Graphs or Graphs lists")

    return inner

def filterbank_handler(func):

    def inner(f, *args, **kwargs):
        if hasattr(f.g, '__call__'):
            return func([f], *args, **kwargs)
        if len(f.g) <= 1:
            return func(f, *args, **kwargs)
        elif len(f.g) > 1:
            output = []
            i = range(len(f.g))
            for ii in i:
                output.append(func(f, *args, i=ii, **kwargs))
            return output

        else:
            raise TypeError("This function only accepts Filters or\
                            Filters lists")
    return inner

def sparsifier(func):

    def inner(*args, **kwargs):
        return sparse.lil_matrix(func(*args, **kwargs))

    return inner

def is_directed(M):
    r"""
    Returns a bool:  True if the graph is directed and false if not

    Parameters
    ----------
    M : sparse matrix or Graph

    Returns
    -------
    is_dir : bool

    Notes
    -----
    The Weight matrix has to be sparse (For now)
    Can also be used to check if a matrix is symetrical

    Examples
    --------
    >>> from scipy import sparse
    >>> from pygsp import graphs, utils
    >>> W = sparse.rand(10,10,0.2)
    >>> G = graphs.Graph(W=W)
    >>> is_directed = utils.is_directed(G.W)

    """
    # To pass a graph or a weight matrix as an argument
    if isinstance(M, pygsp.graphs.Graph):
        W = M.W
    else:
        W = M

    # Python Bug Can't use this in tests
    if np.shape(W) != (1, 1):
        is_dir = np.abs((W - W.T)).sum() != 0
    else:
        is_dir = False

    return is_dir

def estimate_lmax(G):
    r"""
    This function estimates lmax from a Graph object and stores it into the
    graph.

    Parameters
    ----------
    G : Graph object

    Returns
    -------
    lmax : float
        Returns the value of lmax

    Examples
    --------
    Just define a graph an apply the estimation on it

    >>> import pygsp
    >>> import numpy as np
    >>> W = np.arange(16).reshape(4, 4)
    >>> G = pygsp.graphs.Graph(W)
    >>> lmax = pygsp.utils.estimate_lmax(G)

    """
    try:
        lmax = sparse.linalg.eigs(G.L, k=1, tol=5e-3, ncv=10)[0]
        # MAT: lmax=eigs(G.L,1,'lm',opts)
        # On robustness purposes, increasing the error by 1 percent
        lmax *= 1.01
    except ValueError:
        if G.verbose:
            print('GSP_ESTIMATE_LMAX: Cannot use default method')
        lmax = np.max(G.d)
    G.lmax = np.real(lmax)
    return np.real(lmax)

def check_weights(W, verbose=0):
    r"""
    Check the characteristics of the weights matrix

    Parameters
    ----------
    W : weights matrix
        The weights matrix to check
    verbose : int
        Verbosity : 0 no output, 1 prints characteristics (default = 0)

    Returns
    -------
    A dict of bools containing informations about the matrix

    has_inf_val : bool
        True if the matrix has infinite values else false
    has_nan_value : bool
        True if the matrix has a not a number value else false
    is_not_square : bool
        True if the matrix is not square else false
    diag_is_not_zero : bool
        True if the matrix diagonal has not only zero value else false

    Examples
    --------
    >>> from scipy import sparse
    >>> from pygsp import graphs, utils
    >>> W = sparse.rand(10,10,0.2)
    >>> [has_inf_val, has_nan_value, is_not_square, diag_is_not_zero] = utils.check_weights(W)
    GSP_TEST_WEIGHTS: The main diagonal of the weight matrix is not 0!
    >>> weights_chara = utils.check_weights(W)
    GSP_TEST_WEIGHTS: The main diagonal of the weight matrix is not 0!

    """

    has_inf_val = False
    diag_is_not_zero = False
    is_not_square = False
    has_nan_value = False

    if isinf(W.sum()):
        print("GSP_TEST_WEIGHTS: There is an infinite "
              "value in the weight matrix")
        has_inf_val = True

    if abs(W.diagonal()).sum() != 0:
        print("GSP_TEST_WEIGHTS: The main diagonal of "
              "the weight matrix is not 0!")
        diag_is_not_zero = True

    if W.get_shape()[0] != W.get_shape()[1]:
        print("GSP_TEST_WEIGHTS: The weight matrix is "
              "not square!")
        is_not_square = True

    if isnan(W.sum()):
        print("GSP_TEST_WEIGHTS: There is an NaN "
              "value in the weight matrix")
        has_nan_value = True

    return {'has_inf_val': has_inf_val, 'has_nan_value': has_nan_value, 'is_not_square': is_not_square, 'diag_is_not_zero': diag_is_not_zero}

def check_connectivity(G, **kwargs):
    r"""
    Function to check the connectivity of the input graph
    It will call _check_connectivity_directed or _check_connectivity_undirected
    wether the graph is directed or not

    Parameters
    ----------
    G : graph
        Graph to check
    **kwargs : keyowords arguments
        (not implmented yet)

    Returns
    -------
    is_connected : bool
        A bool value telling if the graph is connected
    in_conn : int
        Number of in connections
    out_conn : int
        Number of out connections

    """

    if not hasattr(G, 'directed'):
        G.directed = is_directed(G)
    # Removing the diagonal
    A = G.W - G.W.diagonal()

    if G.directed:
        return _check_connectivity_directed(A, **kwargs)

    else:
        return _check_connectivity_undirected(A, **kwargs)

    pass

def _check_connectivity_directed(A, **kwargs):
    r"""
    Subfunc to check connec in the directed case
    """
    is_connected = (A < 0).any()
    hard_check = (1 - (A.sum(axis=0) > 0)) +\
        (1 - (A.sum(axis=1) > 0)).reshape(1, A.shape[0])

    c = 0
    while c <= sp.shape(A)[0]:
        c_is_connected = (c == 0)
        c += 1
        if c_is_connected:
            break

    r = 0
    while r <= sp.shape(A)[1]:
        r_is_connected = (c == 0)
        r += 1
        if r_is_connected:
            break

    # TODO check axis
    in_conn = (1 - (A.sum(axis=0) > 0))
    out_conn = (1 - (A.sum(axis=1) > 0))

    return is_connected, in_conn, out_conn

def _check_connectivity_undirected(A, **kwargs):
    r"""
    Subfunc to check connec in the undirected case
    """

    is_connected = (A < 0).any()
    c = 0
    while c <= sp.shape(A)[0]:
        c_is_connected = (c == 0)
        c += 1
        if c_is_connected:
            break

    # TODO check axises
    in_conn = (A.sum(axis=1) > 0).nonzero()
    out_conn = in_conn

    if c_is_connected:
        return is_connected, in_conn, out_conn

def distanz(x, y=None):
    r"""
    Calculate the distanz between two colon vectors

    Parameters
    ----------
    x : ndarray
        First colon vector
    y : ndarray
        Second colon vector

    Returns
    -------
    d : ndarray
        Distance between x and y

    Examples
    --------
    >>> import numpy as np
    >>> from pygsp import utils
    >>> x = np.random.rand(16)
    >>> y = np.random.rand(16)
    >>> distanz = utils.distanz(x, y)

    """
    try:
        x.shape[1]
    except IndexError:
        x = x.reshape(1, x.shape[0])

    if y is None:
        y = x

    else:
        try:
            y.shape[1]
        except IndexError:
            y = y.reshape(1, y.shape[0])

    rx, cx = x.shape
    ry, cy = y.shape

    # Size verification
    if rx != ry:
        raise("The sizes of x and y do not fit")

    xx = (x*x).sum(axis=0)
    yy = (y*y).sum(axis=0)
    xy = np.dot(x.T, y)

    d = abs(sp.kron(sp.ones((cy, 1)), xx).T +
            sp.kron(sp.ones((cx, 1)), yy) - 2*xy)

    return np.sqrt(d)

def repmatline(A, ncol=1, nrow=1):
    r"""
    This function repeat the matrix A in a specific manner

    Parameters
    ----------
    A : ndarray
    ncol : Integer
        default is 1
    nrow : Integer
        default is 1

    Returns
    -------
    Ar : Matrix

    Examples
    --------

    For ncol=2 and nrow=3, the matix

                1 2
                3 4
    becomes
                1 1 1 2 2 2
                1 1 1 2 2 2
                3 3 3 4 4 4
                3 3 3 4 4 4
    np.repeat(np.repeat(x, nrow, axis=1), ncol,  axis=0)

    """

    if ncol < 0 or nrow < 0:
        raise ValueError("The number of lines and rows must be greater or\
                         equal to one, or you will get an empty array.")

    return np.repeat(np.repeat(x, ncol, axis=1), nrow, axis=0)

def vec2mat(d, Nf):
    r"""
    Vector to matrix transfor

    Parameters
    ----------
    d : Ndarray
        Data
    Nf : int
        Number of filter

    Returns
    -------
    d : list of ndarray
        Data

    """
    if len(np.shape(d)) == 1:
        M = np.shape(d)[0]
        return np.reshape(d, (M/Nf, Nf), order='F')

    if len(np.shape(d)) == 2:
        M, N = np.shape(d)
        return np.reshape(d, (M/Nf, Nf, N), order='F')

def mat2vec(d):
    raise NotImplementedError

def resistance_distance(G):
    r"""
    Compute the resitance distances of a graph

    Parameters
    ----------
    G : Graph structure or Laplacian matrix (L)
    verbose (bool) : Display parameter - False no log - True display warnings
        Default is True

    Returns
    -------
    rd : distance matrix

    Examples
    --------
    >>>
    >>>
    >>>

    Reference
    ----------
    :cite:`klein1993resistance`

    """
    if isinstance(G, pygsp.graphs.Graph):
        if not G.lap_type == 'combinatorial':
            pygsp.operators.create_laplacian(G, lap_type='combinatorial', get_laplacian_only=False)
            if verbose:
                print('Compute the combinatorial laplacian for the resitance distance')
        L = G.L

    else:
        L = G

    pseudo = np.linalg.pinv(L.todense())
    N = np.shape(L)[0]

    d = np.diagonal(pseudo)
    rd = np.kron(np.ones((1, N)), d) + np.kron(np.ones((N, 1)), d) - pseudo - pseudo.T

    return rd

def symetrize(W, symetrize_type='average'):
    r"""
    Symetrize a matrix

    Parameters
    ----------
        W : sparse matrix
            Weight matrix
        symetrize_type : string
            type of symetrization (default 'average')
        The availlable symetrization_types are:
            'average' : average of W and W^T (default)
            'full'    : copy the missing entries
            'none'    : nothing is done (the matrix might stay unsymetric!)

    Returns
    -------
        W : symetrized matrix

    Examples
    --------
    >>> from pygsp import utils
    >>> W = utils.symetrize(W)
    >>> W = utils.symetrize(W, symetrize_type='average')

    """

    if symetrize_type == 'average':
        W = (W + W.getH())/2.
        return W

    elif symetrize_type == 'full':
        A = W > 0
        M = (A - (A.T * A))
        W = sparse.csr_matrix(W.T)
        W[M.T] = W.T[M.T]

        return W

    elif symetrize_type == 'none':
        return W

    else:
        raise ValueError("Unknown symetrize type")

def tree_depths(A, root):

    if check_connectivity(A) == 0:
        raise ValueError('Graph is not connected')

    N = np.shape(A)[0]
    assigned = root-1
    depths = np.zeros((N))
    parents = np.zeros((N))

    next_to_expand = np.array([root])
    current_depth = 1

    while len(assigned) < N:
        new_entries_whole_round = []
        for i in range(len(next_to_expand)):
            neighbors = np.where(A[next_to_expand[i]] > 1e-7)[0]
            new_entries = np.setdiff1d(neighbors, assigned)
            parents[new_entries] = next_to_expand[i]
            depths[new_entries] = current_depth
            assigned = np.concatenate((assigned, new_entries))
            new_entries_whole_round = np.concatenate((new_entries_whole_round,
                                                      new_entries))

        current_depth = current_depth+1
        next_to_expand = new_entries_whole_round

    return depths, parents

def dummy(a, b, c):
    r"""
    Short description.

    Long description.

    Parameters
    ----------
    a : int
        Description.
    b : array_like
        Description.
    c : bool
        Description.

    Returns
    -------
    d : ndarray
        Description.

    Examples
    --------
    >>> import pygsp
    >>> pygsp.utils.dummy(0, [1, 2, 3], True)
    array([1, 2, 3])

    """
    return np.array(b)
<commit_msg>Remove verbose in utils<commit_after># -*- coding: utf-8 -*-
r"""
This module implements some utilitary functions used throughout the PyGSP box.
"""

import numpy as np
import scipy as sp
from scipy import sparse
from scipy.sparse import linalg
from math import isinf, isnan
import logging

import pygsp

def build_logger(name):
    logger = logging.getLogger(name)

    steam_handler = logging.StreamHandler()
    steam_handler.setLevel(logging.DEBUG)
    steam_handler.setFormatter(formatter)

    formatter = logging.Formatter("%(asctime)s:[%(levelname)s](%(module)s.%(funcName)s): %(message)s")

    logger.addHandler(steam_handler)

    return logger

utils_logger = build_logger(__name__)

def graph_array_handler(func):

    def inner(G, *args, **kwargs):

        if isinstance(G, pygsp.graphs.Graph):
            return func(G, *args, **kwargs)

        elif type(G) is list:
            output = []
            for g in G:
                output.append(func(g, *args, **kwargs))

            return output

        else:
            raise TypeError("This function only accept Graphs or Graphs lists")

    return inner

def filterbank_handler(func):

    def inner(f, *args, **kwargs):
        if hasattr(f.g, '__call__'):
            return func([f], *args, **kwargs)
        if len(f.g) <= 1:
            return func(f, *args, **kwargs)
        elif len(f.g) > 1:
            output = []
            i = range(len(f.g))
            for ii in i:
                output.append(func(f, *args, i=ii, **kwargs))
            return output

        else:
            raise TypeError("This function only accepts Filters or\
                            Filters lists")
    return inner

def sparsifier(func):

    def inner(*args, **kwargs):
        return sparse.lil_matrix(func(*args, **kwargs))

    return inner

def is_directed(M):
    r"""
    Returns a bool:  True if the graph is directed and false if not

    Parameters
    ----------
    M : sparse matrix or Graph

    Returns
    -------
    is_dir : bool

    Notes
    -----
    The Weight matrix has to be sparse (For now)
    Can also be used to check if a matrix is symetrical

    Examples
    --------
    >>> from scipy import sparse
    >>> from pygsp import graphs, utils
    >>> W = sparse.rand(10,10,0.2)
    >>> G = graphs.Graph(W=W)
    >>> is_directed = utils.is_directed(G.W)

    """
    # To pass a graph or a weight matrix as an argument
    if isinstance(M, pygsp.graphs.Graph):
        W = M.W
    else:
        W = M

    # Python Bug Can't use this in tests
    if np.shape(W) != (1, 1):
        is_dir = np.abs((W - W.T)).sum() != 0
    else:
        is_dir = False

    return is_dir

def estimate_lmax(G):
    r"""
    This function estimates lmax from a Graph object and stores it into the
    graph.

    Parameters
    ----------
    G : Graph object

    Returns
    -------
    lmax : float
        Returns the value of lmax

    Examples
    --------
    Just define a graph an apply the estimation on it

    >>> import pygsp
    >>> import numpy as np
    >>> W = np.arange(16).reshape(4, 4)
    >>> G = pygsp.graphs.Graph(W)
    >>> lmax = pygsp.utils.estimate_lmax(G)

    """
    try:
        lmax = sparse.linalg.eigs(G.L, k=1, tol=5e-3, ncv=10)[0]
        # MAT: lmax=eigs(G.L,1,'lm',opts)
        # On robustness purposes, increasing the error by 1 percent
        lmax *= 1.01
    except ValueError:
        utils_logger.warning('GSP_ESTIMATE_LMAX: Cannot use default method')
        lmax = np.max(G.d)
    G.lmax = np.real(lmax)
    return np.real(lmax)

def check_weights(W):
    r"""
    Check the characteristics of the weights matrix

    Parameters
    ----------
    W : weights matrix
        The weights matrix to check

    Returns
    -------
    A dict of bools containing informations about the matrix

    has_inf_val : bool
        True if the matrix has infinite values else false
    has_nan_value : bool
        True if the matrix has a not a number value else false
    is_not_square : bool
        True if the matrix is not square else false
    diag_is_not_zero : bool
        True if the matrix diagonal has not only zero value else false

    Examples
    --------
    >>> from scipy import sparse
    >>> from pygsp import graphs, utils
    >>> W = sparse.rand(10,10,0.2)
    >>> [has_inf_val, has_nan_value, is_not_square, diag_is_not_zero] = utils.check_weights(W)
    GSP_TEST_WEIGHTS: The main diagonal of the weight matrix is not 0!
    >>> weights_chara = utils.check_weights(W)
    GSP_TEST_WEIGHTS: The main diagonal of the weight matrix is not 0!

    """

    has_inf_val = False
    diag_is_not_zero = False
    is_not_square = False
    has_nan_value = False

    if isinf(W.sum()):
        utils_logger.warning("GSP_TEST_WEIGHTS: There is an infinite "
              "value in the weight matrix")
        has_inf_val = True

    if abs(W.diagonal()).sum() != 0:
        utils_logger.warning("GSP_TEST_WEIGHTS: The main diagonal of "
              "the weight matrix is not 0!")
        diag_is_not_zero = True

    if W.get_shape()[0] != W.get_shape()[1]:
        utils_logger.warning("GSP_TEST_WEIGHTS: The weight matrix is "
              "not square!")
        is_not_square = True

    if isnan(W.sum()):
        utils_logger.warning("GSP_TEST_WEIGHTS: There is an NaN "
              "value in the weight matrix")
        has_nan_value = True

    return {'has_inf_val': has_inf_val, 'has_nan_value': has_nan_value, 'is_not_square': is_not_square, 'diag_is_not_zero': diag_is_not_zero}

def check_connectivity(G, **kwargs):
    r"""
    Function to check the connectivity of the input graph
    It will call _check_connectivity_directed or _check_connectivity_undirected
    wether the graph is directed or not

    Parameters
    ----------
    G : graph
        Graph to check
    **kwargs : keyowords arguments
        (not implmented yet)

    Returns
    -------
    is_connected : bool
        A bool value telling if the graph is connected
    in_conn : int
        Number of in connections
    out_conn : int
        Number of out connections

    """

    if not hasattr(G, 'directed'):
        G.directed = is_directed(G)
    # Removing the diagonal
    A = G.W - G.W.diagonal()

    if G.directed:
        return _check_connectivity_directed(A, **kwargs)

    else:
        return _check_connectivity_undirected(A, **kwargs)

    pass

def _check_connectivity_directed(A, **kwargs):
    r"""
    Subfunc to check connec in the directed case
    """
    is_connected = (A < 0).any()
    hard_check = (1 - (A.sum(axis=0) > 0)) +\
        (1 - (A.sum(axis=1) > 0)).reshape(1, A.shape[0])

    c = 0
    while c <= sp.shape(A)[0]:
        c_is_connected = (c == 0)
        c += 1
        if c_is_connected:
            break

    r = 0
    while r <= sp.shape(A)[1]:
        r_is_connected = (c == 0)
        r += 1
        if r_is_connected:
            break

    # TODO check axis
    in_conn = (1 - (A.sum(axis=0) > 0))
    out_conn = (1 - (A.sum(axis=1) > 0))

    return is_connected, in_conn, out_conn

def _check_connectivity_undirected(A, **kwargs):
    r"""
    Subfunc to check connec in the undirected case
    """

    is_connected = (A < 0).any()
    c = 0
    while c <= sp.shape(A)[0]:
        c_is_connected = (c == 0)
        c += 1
        if c_is_connected:
            break

    # TODO check axises
    in_conn = (A.sum(axis=1) > 0).nonzero()
    out_conn = in_conn

    if c_is_connected:
        return is_connected, in_conn, out_conn

def distanz(x, y=None):
    r"""
    Calculate the distanz between two colon vectors

    Parameters
    ----------
    x : ndarray
        First colon vector
    y : ndarray
        Second colon vector

    Returns
    -------
    d : ndarray
        Distance between x and y

    Examples
    --------
    >>> import numpy as np
    >>> from pygsp import utils
    >>> x = np.random.rand(16)
    >>> y = np.random.rand(16)
    >>> distanz = utils.distanz(x, y)

    """
    try:
        x.shape[1]
    except IndexError:
        x = x.reshape(1, x.shape[0])

    if y is None:
        y = x

    else:
        try:
            y.shape[1]
        except IndexError:
            y = y.reshape(1, y.shape[0])

    rx, cx = x.shape
    ry, cy = y.shape

    # Size verification
    if rx != ry:
        raise("The sizes of x and y do not fit")

    xx = (x*x).sum(axis=0)
    yy = (y*y).sum(axis=0)
    xy = np.dot(x.T, y)

    d = abs(sp.kron(sp.ones((cy, 1)), xx).T +
            sp.kron(sp.ones((cx, 1)), yy) - 2*xy)

    return np.sqrt(d)

def repmatline(A, ncol=1, nrow=1):
    r"""
    This function repeat the matrix A in a specific manner

    Parameters
    ----------
    A : ndarray
    ncol : Integer
        default is 1
    nrow : Integer
        default is 1

    Returns
    -------
    Ar : Matrix

    Examples
    --------

    For ncol=2 and nrow=3, the matix

                1 2
                3 4
    becomes
                1 1 1 2 2 2
                1 1 1 2 2 2
                3 3 3 4 4 4
                3 3 3 4 4 4
    np.repeat(np.repeat(x, nrow, axis=1), ncol,  axis=0)

    """

    if ncol < 0 or nrow < 0:
        raise ValueError("The number of lines and rows must be greater or\
                         equal to one, or you will get an empty array.")

    return np.repeat(np.repeat(x, ncol, axis=1), nrow, axis=0)

def vec2mat(d, Nf):
    r"""
    Vector to matrix transfor

    Parameters
    ----------
    d : Ndarray
        Data
    Nf : int
        Number of filter

    Returns
    -------
    d : list of ndarray
        Data

    """
    if len(np.shape(d)) == 1:
        M = np.shape(d)[0]
        return np.reshape(d, (M/Nf, Nf), order='F')

    if len(np.shape(d)) == 2:
        M, N = np.shape(d)
        return np.reshape(d, (M/Nf, Nf, N), order='F')

def mat2vec(d):
    raise NotImplementedError

def resistance_distance(G):
    r"""
    Compute the resitance distances of a graph

    Parameters
    ----------
    G : Graph structure or Laplacian matrix (L)

    Returns
    -------
    rd : distance matrix

    Examples
    --------
    >>>
    >>>
    >>>

    Reference
    ----------
    :cite:`klein1993resistance`

    """
    if isinstance(G, pygsp.graphs.Graph):
        if not G.lap_type == 'combinatorial':
            utils_logger.info('Compute the combinatorial laplacian for the resitance distance')
            pygsp.operators.create_laplacian(G, lap_type='combinatorial', get_laplacian_only=False)
        L = G.L

    else:
        L = G

    pseudo = np.linalg.pinv(L.todense())
    N = np.shape(L)[0]

    d = np.diagonal(pseudo)
    rd = np.kron(np.ones((1, N)), d) + np.kron(np.ones((N, 1)), d) - pseudo - pseudo.T

    return rd

def symetrize(W, symetrize_type='average'):
    r"""
    Symetrize a matrix

    Parameters
    ----------
        W : sparse matrix
            Weight matrix
        symetrize_type : string
            type of symetrization (default 'average')
        The availlable symetrization_types are:
            'average' : average of W and W^T (default)
            'full'    : copy the missing entries
            'none'    : nothing is done (the matrix might stay unsymetric!)

    Returns
    -------
        W : symetrized matrix

    Examples
    --------
    >>> from pygsp import utils
    >>> W = utils.symetrize(W)
    >>> W = utils.symetrize(W, symetrize_type='average')

    """

    if symetrize_type == 'average':
        W = (W + W.getH())/2.
        return W

    elif symetrize_type == 'full':
        A = W > 0
        M = (A - (A.T * A))
        W = sparse.csr_matrix(W.T)
        W[M.T] = W.T[M.T]

        return W

    elif symetrize_type == 'none':
        return W

    else:
        raise ValueError("Unknown symetrize type")

def tree_depths(A, root):

    if check_connectivity(A) == 0:
        raise ValueError('Graph is not connected')

    N = np.shape(A)[0]
    assigned = root-1
    depths = np.zeros((N))
    parents = np.zeros((N))

    next_to_expand = np.array([root])
    current_depth = 1

    while len(assigned) < N:
        new_entries_whole_round = []
        for i in range(len(next_to_expand)):
            neighbors = np.where(A[next_to_expand[i]] > 1e-7)[0]
            new_entries = np.setdiff1d(neighbors, assigned)
            parents[new_entries] = next_to_expand[i]
            depths[new_entries] = current_depth
            assigned = np.concatenate((assigned, new_entries))
            new_entries_whole_round = np.concatenate((new_entries_whole_round,
                                                      new_entries))

        current_depth = current_depth+1
        next_to_expand = new_entries_whole_round

    return depths, parents

def dummy(a, b, c):
    r"""
    Short description.

    Long description.

    Parameters
    ----------
    a : int
        Description.
    b : array_like
        Description.
    c : bool
        Description.

    Returns
    -------
    d : ndarray
        Description.

    Examples
    --------
    >>> import pygsp
    >>> pygsp.utils.dummy(0, [1, 2, 3], True)
    array([1, 2, 3])

    """
    return np.array(b)
<|endoftext|>


<commit_before>#
# Copyright (c) SAS Institute Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import re

from lxml import etree

from . import errors
from .artifact import Artifact
from .utils import memoize
from .versioning import VersionRange

POM_PARSER = etree.XMLParser(
    recover=True,
    remove_comments=True,
    remove_pis=True,
    )
PROPERTY_RE = re.compile(r'\$\{(.*?)\}')
STRIP_NAMESPACE_RE = re.compile(r"<project(.|\s)*?>")

class Pom(Artifact):
    """Parse a pom file into a python object
    """

    RANGE_CHARS = ('[', '(', ']', ')')

    __slots__ = ("_client", "_parent", "_dep_mgmt", "_dependencies",
                 "_properties", "_artifacts", "_xml")

    def __init__(self, coordinate, client):
        super(Pom, self).__init__(coordinate)
        self._client = client
        with client.get_artifact(self._coordinate).contents as fh:
            xml = fh.read()
        self._xml = etree.fromstring(
            STRIP_NAMESPACE_RE.sub('<project>', xml[xml.find('<project'):], 1),
            parser=POM_PARSER,
            )

        # dynamic attributes
        self._parent = None
        self._dep_mgmt = None
        self._dependencies = None
        self._properties = None
        self._artifacts = NotImplemented

    def _find_compile_deps(self, xml=None):
        if xml is None:
            xml = self._xml
        dependencies = set()
        # find all non-optional, compile dependencies
        for elem in xml.findall("dependencies/dependency"):
            group = self._replace_properties(elem.findtext("groupId"))
            artifact = self._replace_properties(elem.findtext("artifactId"))
            optional = elem.findtext("optional")

            if optional is None or optional == "false":
                # this is a required dependency
                if (group, artifact) in self.dependency_management:
                    spec, scope = self.dependency_management[(group, artifact)]
                else:
                    spec = elem.findtext("version")
                    scope = elem.findtext("scope")
                    if spec is None:
                        # FIXME: Default to the latest released version if no
                        # version is specified. I'm not sure if this is the
                        # correct behavior, but let's try it for now.
                        spec = 'latest.release'
                    spec = self._replace_properties(spec)

                if scope in (None, "compile", "import"):
                    if any(ch for ch in spec if ch in self.RANGE_CHARS):
                        available_versions = self._client.find_artifacts(
                            "%s:%s" % (group, artifact))
                        version = self.pick_version(spec, available_versions)
                    elif spec.lower() in ("latest.release", "release",
                                          "latest.integration", "latest"):
                        metadata = self._client.get_maven_metadata(
                            "%s:%s" % (group, artifact))
                        metadata = etree.fromstring(metadata)
                        if (spec.lower() == "latest.release"
                                or spec.lower() == "release"):
                            version = metadata.findtext("versioning/release")
                        elif (spec.lower() == "latest.integration"
                                or spec.lower() == "latest"):
                            version = metadata.findtext("versioning/latest")
                    else:
                        version = spec

                    if version is None:
                        raise errors.MissingArtifactError(
                            "%s:%s:%s" % (group, artifact, spec))

                    dependencies.add(
                        self._pom_factory(group, artifact, version))

        return dependencies

    def _find_dependency_management(self, xml=None):
        if xml is None:
            xml = self._xml
        dep_mgmt = {}
        import_mgmt = {}

        for elem in xml.findall(
                "dependencyManagement/dependencies/dependency"):
            group = self._replace_properties(elem.findtext("groupId"))
            artifact = self._replace_properties(elem.findtext("artifactId"))
            version = self._replace_properties(elem.findtext("version"))

            scope = elem.findtext("scope")
            if scope is not None and scope == "import":
                import_pom = self._pom_factory(group, artifact, version)
                import_mgmt.update(import_pom.dependency_management)
            dep_mgmt[(group, artifact)] = (version, scope)

        import_mgmt.update(dep_mgmt)
        return import_mgmt

    def _find_import_deps(self):
        dependencies = set()
        # process dependency management to find imports
        for group, artifact in self.dependency_management:
            version, scope = self.dependency_management[(group, artifact)]
            if scope == "import":
                dependencies.add(self._pom_factory(group, artifact, version))

        return dependencies

    def _find_prerequisites(self):
        properties = {}
        # get prerequisites
        prereqs = self._xml.find("prerequisites")
        if prereqs is not None:
            for elem in prereqs:
                properties['prerequisites.' + elem.tag] = elem.text
                properties['project.prerequisites.' + elem.tag] = elem.text

        return properties

    def _find_profiles(self):
        active_profiles = []
        default_profiles = []
        for p in self._xml.findall("profiles/profile"):
            if p.findtext("activation/activeByDefault") == "true":
                default_profiles.append(p)
            else:
                jdk = p.findtext("activation/jdk")
                if jdk is not None:
                    # attempt some clean up
                    if (jdk.startswith('[') or jdk.startswith("![")) \
                            and jdk.endswith(','):
                        # assume they left off the )
                        jdk += ')'

                    # TODO: make the JDK version selectable
                    if jdk.startswith('!'):
                        vr = VersionRange.fromstring(jdk[1:])
                        if (vr.version and "1.8" != vr.version) \
                                or (not vr.version and "1.8" not in vr):
                            active_profiles.append(p)
                    else:
                        vr = VersionRange.fromstring(jdk)
                        if (vr.version and "1.8" == vr.version) \
                                or (not vr.version and "1.8" in vr):
                            active_profiles.append(p)

        if active_profiles:
            return active_profiles
        else:
            return default_profiles

    def _find_properties(self, xml=None):
        if xml is None:
            xml = self._xml
        properties = {}
        project_properties = xml.find('properties')
        if project_properties is not None:
            for prop in project_properties.iterchildren():
                if prop.tag == 'property':
                    name = prop.get('name')
                    value = prop.get('value')
                else:
                    name = prop.tag
                    value = prop.text
                properties[name] = value
        return properties

    def _find_relocations(self, xml=None):
        if xml is None:
            xml = self._xml
        dependencies = set()
        # process distributionManagement for relocation
        relocation = xml.find("distributionManagement/relocation")
        if relocation is not None:
            group = relocation.findtext("groupId")
            if group is None:
                group = self.group_id
            else:
                group = self._replace_properties(group)

            artifact = relocation.findtext("artifactId")
            if artifact is None:
                artifact = self.artifact_id
            else:
                artifact = self._replace_properties(artifact)

            version = relocation.findtext("version")
            if version is None:
                version = self.version
            else:
                version = self._replace_properties(version)

            dependencies.add(self._pom_factory(group, artifact, version))

        return dependencies

    def _pom_factory(self, group, artifact, version):
        return Pom("%s:%s:pom:%s" % (group, artifact, version), self._client)

    def _replace_properties(self, text, properties=None):
        if properties is None:
            properties = self.properties

        def subfunc(matchobj):
            key = matchobj.group(1)
            return properties.get(key)

        result = PROPERTY_RE.sub(subfunc, text)
        while result and PROPERTY_RE.match(result):
            result = PROPERTY_RE.sub(subfunc, result)
        return result.strip()

    @staticmethod
    def pick_version(spec, artifacts):
        """Pick a version from *versions* according to the spec

        Convert spec into maven version range and return the first version in
        *versions* that is within the range.

        :param str spec: a maven version range spec or gradle dynamic version
        :param versions: list of available versions for this artifact
        :type versions: [:py:class:`pymaven.Version`, ...]
        :return: the newest version that matches the spec
        :rtype: str or None
        """
        range = VersionRange.fromstring(spec)
        for artifact in artifacts:
            if artifact.version in range:
                return str(artifact.version)

    @property
    @memoize("_dependencies")
    def dependencies(self):
        dependencies = set()

        # we depend on our parent
        if self.parent is not None:
            dependencies.add(self.parent)

        dependencies.update(self._find_import_deps())
        dependencies.update(self._find_compile_deps())
        dependencies.update(self._find_relocations())

        for profile in self._find_profiles():
            dependencies.update(self._find_compile_deps(profile))
            dependencies.update(self._find_relocations(profile))

        return dependencies

    @property
    @memoize("_dep_mgmt")
    def dependency_management(self):
        dep_mgmt = {}
        import_mgmt = {}

        # add parent's block first so we can override it
        if self.parent is not None:
            dep_mgmt.update(self.parent.dependency_management)

        dep_mgmt.update(self._find_dependency_management())
        for profile in self._find_profiles():
            dep_mgmt.update(self._find_dependency_management(profile))

        return dep_mgmt

    @property
    @memoize("_parent")
    def parent(self):
        parent = self._xml.find("parent")
        if parent is not None:
            group = parent.findtext("groupId").strip()
            artifact = parent.findtext("artifactId").strip()
            version = parent.findtext("version").strip()
            return self._pom_factory(group, artifact, version)

    @property
    @memoize("_properties")
    def properties(self):
        properties = {}

        if self.parent is not None:
            properties.update(self.parent.properties)
            properties['parent.groupId'] = self.parent.group_id
            properties['parent.artifactId'] = self.parent.artifact_id
            properties['parent.version'] = str(self.parent.version)
            properties['project.parent.groupId'] = self.parent.group_id
            properties['project.parent.artifactId'] = self.parent.artifact_id
            properties['project.parent.version'] = str(self.parent.version)

        # built-in properties
        properties['artifactId'] = self.artifact_id
        properties['groupId'] = self.group_id
        properties['version'] = str(self.version)
        properties['project.artifactId'] = self.artifact_id
        properties['project.groupId'] = self.group_id
        properties['project.version'] = str(self.version)
        properties['pom.artifactId'] = self.artifact_id
        properties['pom.groupId'] = self.group_id
        properties['pom.version'] = str(self.version)

        properties.update(self._find_properties())
        properties.update(self._find_prerequisites())

        for profile in self._find_profiles():
            profile_properties = profile.find("properties")
            if profile_properties is not None:
                for prop in profile_properties.iterchildren():
                    properties[prop.tag] = prop.text
        return properties
<commit_msg>Remove artifacts attribute from Pom object<commit_after>#
# Copyright (c) SAS Institute Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import re

from lxml import etree

from . import errors
from .artifact import Artifact
from .utils import memoize
from .versioning import VersionRange

POM_PARSER = etree.XMLParser(
    recover=True,
    remove_comments=True,
    remove_pis=True,
    )
PROPERTY_RE = re.compile(r'\$\{(.*?)\}')
STRIP_NAMESPACE_RE = re.compile(r"<project(.|\s)*?>")

class Pom(Artifact):
    """Parse a pom file into a python object
    """

    RANGE_CHARS = ('[', '(', ']', ')')

    __slots__ = ("_client", "_parent", "_dep_mgmt", "_dependencies",
                 "_properties", "_xml")

    def __init__(self, coordinate, client):
        super(Pom, self).__init__(coordinate)
        self._client = client
        with client.get_artifact(self._coordinate).contents as fh:
            xml = fh.read()
        self._xml = etree.fromstring(
            STRIP_NAMESPACE_RE.sub('<project>', xml[xml.find('<project'):], 1),
            parser=POM_PARSER,
            )

        # dynamic attributes
        self._parent = None
        self._dep_mgmt = None
        self._dependencies = None
        self._properties = None

    def _find_compile_deps(self, xml=None):
        if xml is None:
            xml = self._xml
        dependencies = set()
        # find all non-optional, compile dependencies
        for elem in xml.findall("dependencies/dependency"):
            group = self._replace_properties(elem.findtext("groupId"))
            artifact = self._replace_properties(elem.findtext("artifactId"))
            optional = elem.findtext("optional")

            if optional is None or optional == "false":
                # this is a required dependency
                if (group, artifact) in self.dependency_management:
                    spec, scope = self.dependency_management[(group, artifact)]
                else:
                    spec = elem.findtext("version")
                    scope = elem.findtext("scope")
                    if spec is None:
                        # FIXME: Default to the latest released version if no
                        # version is specified. I'm not sure if this is the
                        # correct behavior, but let's try it for now.
                        spec = 'latest.release'
                    spec = self._replace_properties(spec)

                if scope in (None, "compile", "import"):
                    if any(ch for ch in spec if ch in self.RANGE_CHARS):
                        available_versions = self._client.find_artifacts(
                            "%s:%s" % (group, artifact))
                        version = self.pick_version(spec, available_versions)
                    elif spec.lower() in ("latest.release", "release",
                                          "latest.integration", "latest"):
                        metadata = self._client.get_maven_metadata(
                            "%s:%s" % (group, artifact))
                        metadata = etree.fromstring(metadata)
                        if (spec.lower() == "latest.release"
                                or spec.lower() == "release"):
                            version = metadata.findtext("versioning/release")
                        elif (spec.lower() == "latest.integration"
                                or spec.lower() == "latest"):
                            version = metadata.findtext("versioning/latest")
                    else:
                        version = spec

                    if version is None:
                        raise errors.MissingArtifactError(
                            "%s:%s:%s" % (group, artifact, spec))

                    dependencies.add(
                        self._pom_factory(group, artifact, version))

        return dependencies

    def _find_dependency_management(self, xml=None):
        if xml is None:
            xml = self._xml
        dep_mgmt = {}
        import_mgmt = {}

        for elem in xml.findall(
                "dependencyManagement/dependencies/dependency"):
            group = self._replace_properties(elem.findtext("groupId"))
            artifact = self._replace_properties(elem.findtext("artifactId"))
            version = self._replace_properties(elem.findtext("version"))

            scope = elem.findtext("scope")
            if scope is not None and scope == "import":
                import_pom = self._pom_factory(group, artifact, version)
                import_mgmt.update(import_pom.dependency_management)
            dep_mgmt[(group, artifact)] = (version, scope)

        import_mgmt.update(dep_mgmt)
        return import_mgmt

    def _find_import_deps(self):
        dependencies = set()
        # process dependency management to find imports
        for group, artifact in self.dependency_management:
            version, scope = self.dependency_management[(group, artifact)]
            if scope == "import":
                dependencies.add(self._pom_factory(group, artifact, version))

        return dependencies

    def _find_prerequisites(self):
        properties = {}
        # get prerequisites
        prereqs = self._xml.find("prerequisites")
        if prereqs is not None:
            for elem in prereqs:
                properties['prerequisites.' + elem.tag] = elem.text
                properties['project.prerequisites.' + elem.tag] = elem.text

        return properties

    def _find_profiles(self):
        active_profiles = []
        default_profiles = []
        for p in self._xml.findall("profiles/profile"):
            if p.findtext("activation/activeByDefault") == "true":
                default_profiles.append(p)
            else:
                jdk = p.findtext("activation/jdk")
                if jdk is not None:
                    # attempt some clean up
                    if (jdk.startswith('[') or jdk.startswith("![")) \
                            and jdk.endswith(','):
                        # assume they left off the )
                        jdk += ')'

                    # TODO: make the JDK version selectable
                    if jdk.startswith('!'):
                        vr = VersionRange.fromstring(jdk[1:])
                        if (vr.version and "1.8" != vr.version) \
                                or (not vr.version and "1.8" not in vr):
                            active_profiles.append(p)
                    else:
                        vr = VersionRange.fromstring(jdk)
                        if (vr.version and "1.8" == vr.version) \
                                or (not vr.version and "1.8" in vr):
                            active_profiles.append(p)

        if active_profiles:
            return active_profiles
        else:
            return default_profiles

    def _find_properties(self, xml=None):
        if xml is None:
            xml = self._xml
        properties = {}
        project_properties = xml.find('properties')
        if project_properties is not None:
            for prop in project_properties.iterchildren():
                if prop.tag == 'property':
                    name = prop.get('name')
                    value = prop.get('value')
                else:
                    name = prop.tag
                    value = prop.text
                properties[name] = value
        return properties

    def _find_relocations(self, xml=None):
        if xml is None:
            xml = self._xml
        dependencies = set()
        # process distributionManagement for relocation
        relocation = xml.find("distributionManagement/relocation")
        if relocation is not None:
            group = relocation.findtext("groupId")
            if group is None:
                group = self.group_id
            else:
                group = self._replace_properties(group)

            artifact = relocation.findtext("artifactId")
            if artifact is None:
                artifact = self.artifact_id
            else:
                artifact = self._replace_properties(artifact)

            version = relocation.findtext("version")
            if version is None:
                version = self.version
            else:
                version = self._replace_properties(version)

            dependencies.add(self._pom_factory(group, artifact, version))

        return dependencies

    def _pom_factory(self, group, artifact, version):
        return Pom("%s:%s:pom:%s" % (group, artifact, version), self._client)

    def _replace_properties(self, text, properties=None):
        if properties is None:
            properties = self.properties

        def subfunc(matchobj):
            key = matchobj.group(1)
            return properties.get(key)

        result = PROPERTY_RE.sub(subfunc, text)
        while result and PROPERTY_RE.match(result):
            result = PROPERTY_RE.sub(subfunc, result)
        return result.strip()

    @staticmethod
    def pick_version(spec, artifacts):
        """Pick a version from *versions* according to the spec

        Convert spec into maven version range and return the first version in
        *versions* that is within the range.

        :param str spec: a maven version range spec or gradle dynamic version
        :param versions: list of available versions for this artifact
        :type versions: [:py:class:`pymaven.Version`, ...]
        :return: the newest version that matches the spec
        :rtype: str or None
        """
        range = VersionRange.fromstring(spec)
        for artifact in artifacts:
            if artifact.version in range:
                return str(artifact.version)

    @property
    @memoize("_dependencies")
    def dependencies(self):
        dependencies = set()

        # we depend on our parent
        if self.parent is not None:
            dependencies.add(self.parent)

        dependencies.update(self._find_import_deps())
        dependencies.update(self._find_compile_deps())
        dependencies.update(self._find_relocations())

        for profile in self._find_profiles():
            dependencies.update(self._find_compile_deps(profile))
            dependencies.update(self._find_relocations(profile))

        return dependencies

    @property
    @memoize("_dep_mgmt")
    def dependency_management(self):
        dep_mgmt = {}
        import_mgmt = {}

        # add parent's block first so we can override it
        if self.parent is not None:
            dep_mgmt.update(self.parent.dependency_management)

        dep_mgmt.update(self._find_dependency_management())
        for profile in self._find_profiles():
            dep_mgmt.update(self._find_dependency_management(profile))

        return dep_mgmt

    @property
    @memoize("_parent")
    def parent(self):
        parent = self._xml.find("parent")
        if parent is not None:
            group = parent.findtext("groupId").strip()
            artifact = parent.findtext("artifactId").strip()
            version = parent.findtext("version").strip()
            return self._pom_factory(group, artifact, version)

    @property
    @memoize("_properties")
    def properties(self):
        properties = {}

        if self.parent is not None:
            properties.update(self.parent.properties)
            properties['parent.groupId'] = self.parent.group_id
            properties['parent.artifactId'] = self.parent.artifact_id
            properties['parent.version'] = str(self.parent.version)
            properties['project.parent.groupId'] = self.parent.group_id
            properties['project.parent.artifactId'] = self.parent.artifact_id
            properties['project.parent.version'] = str(self.parent.version)

        # built-in properties
        properties['artifactId'] = self.artifact_id
        properties['groupId'] = self.group_id
        properties['version'] = str(self.version)
        properties['project.artifactId'] = self.artifact_id
        properties['project.groupId'] = self.group_id
        properties['project.version'] = str(self.version)
        properties['pom.artifactId'] = self.artifact_id
        properties['pom.groupId'] = self.group_id
        properties['pom.version'] = str(self.version)

        properties.update(self._find_properties())
        properties.update(self._find_prerequisites())

        for profile in self._find_profiles():
            profile_properties = profile.find("properties")
            if profile_properties is not None:
                for prop in profile_properties.iterchildren():
                    properties[prop.tag] = prop.text
        return properties
<|endoftext|>


<commit_before>from django.db import models

# Create your models here.

class News(models.Model):
    title = models.TextField(max_length=10000000000000)
    description = models.TextField(max_length=10000000000000000000000)
    url = models.URLField()
    date = models.CharField(max_length=255)
    url_image = models.TextField(max_length=500)
    source = models.CharField(max_length=255)
    last_updated = models.CharField(max_length=255)

    def __str__(self):
        return self.title

    class Meta:
        ordering = ('id',)
<commit_msg>Update models.py<commit_after>from django.db import models

# Create your models here.

class News(models.Model):
    title = models.TextField(max_length=10000000000000)
    description = models.TextField(max_length=10000000000000000000000)
    url = models.URLField()
    date = models.CharField(max_length=255)
    url_image = models.TextField(max_length=500)
    source = models.CharField(max_length=255)
    latest_updated = models.CharField(max_length=255) #Ultima fecha en que se actualizó

    def __str__(self):
        return self.title

    class Meta:
        ordering = ('id',)
<|endoftext|>