<commit_before>/*************************************************************************
 *
 *  $RCSfile: CRC32.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: mtg $ $Date: 2001-04-27 14:56:05 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): Martin Gallwey (gallwey@sun.com)
 *
 *
 ************************************************************************/
#ifndef _CRC32_HXX
#define _CRC32_HXX

#ifndef _COM_SUN_STAR_UNO_SEQUENCE_H_
#include <com/sun/star/uno/Sequence.h>
#endif
#ifndef _COM_SUN_STAR_UNO_RUNTIMEEXCEPTION_HDL_
#include <com/sun/star/uno/RuntimeException.hdl>
#endif

class CRC32
{
private:
    sal_uInt32 nCRC;
public:
    CRC32();
    ~CRC32();
    void SAL_CALL updateByte (sal_Int8 nByte)
        throw(::com::sun::star::uno::RuntimeException);
    void SAL_CALL updateSegment(const ::com::sun::star::uno::Sequence< sal_Int8 > &b, sal_Int32 off, sal_Int32 len)
        throw(::com::sun::star::uno::RuntimeException);
    void SAL_CALL update(const ::com::sun::star::uno::Sequence< sal_Int8 > &b)
        throw(::com::sun::star::uno::RuntimeException);
    sal_Int32 SAL_CALL getValue()
        throw(::com::sun::star::uno::RuntimeException);
    void SAL_CALL reset()
        throw(::com::sun::star::uno::RuntimeException);
};

#endif
<commit_msg>#87099# Added updateStream method<commit_after>/*************************************************************************
 *
 *  $RCSfile: CRC32.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: mtg $ $Date: 2001-05-31 09:37:33 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): Martin Gallwey (gallwey@sun.com)
 *
 *
 ************************************************************************/
#ifndef _CRC32_HXX
#define _CRC32_HXX

#ifndef _COM_SUN_STAR_UNO_SEQUENCE_H_
#include <com/sun/star/uno/Sequence.h>
#endif
#ifndef _COM_SUN_STAR_UNO_RUNTIMEEXCEPTION_HPP_
#include <com/sun/star/uno/RuntimeException.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
#include <com/sun/star/io/XInputStream.hpp>
#endif

class CRC32
{
private:
    sal_uInt32 nCRC;
public:
    CRC32();
    ~CRC32();
    void SAL_CALL updateStream (::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > & xStream)
        throw(::com::sun::star::uno::RuntimeException);
    void SAL_CALL updateByte (sal_Int8 nByte)
        throw(::com::sun::star::uno::RuntimeException);
    void SAL_CALL updateSegment(const ::com::sun::star::uno::Sequence< sal_Int8 > &b, sal_Int32 off, sal_Int32 len)
        throw(::com::sun::star::uno::RuntimeException);
    void SAL_CALL update(const ::com::sun::star::uno::Sequence< sal_Int8 > &b)
        throw(::com::sun::star::uno::RuntimeException);
    sal_Int32 SAL_CALL getValue()
        throw(::com::sun::star::uno::RuntimeException);
    void SAL_CALL reset()
        throw(::com::sun::star::uno::RuntimeException);
};

#endif
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qbluetoothtransferreply_symbian_p.h"

#include <QDebug>
#include <QFile>

QTM_BEGIN_NAMESPACE

QBluetoothTransferReplySymbian::QBluetoothTransferReplySymbian(QIODevice *input, QObject *parent)
:   QBluetoothTransferReply(parent), m_source(input), CActive(EPriorityStandard), m_client(NULL),
    m_running(false), m_finished(false)
{
}

/*!
    Destroys the QBluetoothTransferReply object.
*/
QBluetoothTransferReplySymbian::~QBluetoothTransferReplySymbian()
{
    Cancel();

    delete m_object;
    m_object = NULL;

    delete m_client;
    m_client = NULL;

}

void QBluetoothTransferReplySymbian::setAddress(const QBluetoothAddress &address)
{
    m_address = address;
}

bool QBluetoothTransferReplySymbian::start()
{
    m_running = true;

    TObexBluetoothProtocolInfo protocolInfo;
    TBTDevAddr deviceAddress(m_address.toUInt64());

    protocolInfo.iTransport.Copy(KBTSProtocol);
    protocolInfo.iAddr.SetBTAddr(deviceAddress);
    //protocolInfo.iAddr.SetPort( /*set port here*/ );

    if ( m_client )
        {
        delete m_client;
        m_client = NULL;
        }
    m_client = CObexClient::NewL( protocolInfo );

    m_client->Connect( iStatus );

    m_state = EConnecting;
    SetActive();
    return true;
}

/*!
    Returns true if this reply has finished; otherwise returns false.
*/
bool QBluetoothTransferReplySymbian::isFinished() const
{
    return m_finished;
}

/*!
    Returns true if this reply is running; otherwise returns false.
*/
bool QBluetoothTransferReplySymbian::isRunning() const
{
    return m_running;
}

void QBluetoothTransferReplySymbian::abort()
{
    qDebug() << "Abort() is not implemented";
}

qint64 QBluetoothTransferReplySymbian::readData(char*, qint64)
{
    return 0;
}

qint64 QBluetoothTransferReplySymbian::writeData(const char*, qint64)
{
    return 0;
}

QBluetoothTransferReply::TransferError QBluetoothTransferReplySymbian::error() const
{
    return NoError;
}

QString QBluetoothTransferReplySymbian::errorString() const
{
    return QString();
}

void QBluetoothTransferReplySymbian::DoCancel()
{
}

void QBluetoothTransferReplySymbian::RunL()
{
    switch ( m_state ) {
        case EConnecting:
            m_state = ESending;
            sendObject();
            break;
        case ESending:
            m_state = EDisconnecting;
            disconnect();
            break;
        case EDisconnecting:
            m_state = EIdle;
            break;
        default:
            break;
    }

}

void QBluetoothTransferReplySymbian::sendObject()
{
    delete m_object;
    m_object = NULL;
    TRAPD(err, m_object = CObexFileObject::NewL());
    if (!err) {
        QFile *file = qobject_cast<QFile *>(m_source);

        TPtrC16 str(reinterpret_cast<const TUint16*>(file->fileName().utf16()));
        TRAPD(error, m_object->InitFromFileL( str ));
        if (!error) {
            m_client->Put( *m_object, iStatus );
            SetActive();
        }
    }
}

void QBluetoothTransferReplySymbian::disconnect()
{
    if ( m_state == ESending ) {
        m_client->Disconnect( iStatus );
        SetActive();
    }
}

#include "moc_qbluetoothtransferreply_symbian_p.cpp"

QTM_END_NAMESPACE
<commit_msg>implementation for QBluetoothTransferReplySymbian::DoCancel<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qbluetoothtransferreply_symbian_p.h"

#include <QDebug>
#include <QFile>

QTM_BEGIN_NAMESPACE

QBluetoothTransferReplySymbian::QBluetoothTransferReplySymbian(QIODevice *input, QObject *parent)
:   QBluetoothTransferReply(parent), m_source(input), CActive(EPriorityStandard), m_client(NULL),
    m_running(false), m_finished(false)
{
}

/*!
    Destroys the QBluetoothTransferReply object.
*/
QBluetoothTransferReplySymbian::~QBluetoothTransferReplySymbian()
{
    Cancel();

    delete m_object;
    m_object = NULL;

    delete m_client;
    m_client = NULL;

}

void QBluetoothTransferReplySymbian::setAddress(const QBluetoothAddress &address)
{
    m_address = address;
}

bool QBluetoothTransferReplySymbian::start()
{
    m_running = true;

    TObexBluetoothProtocolInfo protocolInfo;
    TBTDevAddr deviceAddress(m_address.toUInt64());

    protocolInfo.iTransport.Copy(KBTSProtocol);
    protocolInfo.iAddr.SetBTAddr(deviceAddress);
    //protocolInfo.iAddr.SetPort( /*set port here*/ );

    if ( m_client ) {
        delete m_client;
        m_client = NULL;
    }

    TRAPD( err, m_client = CObexClient::NewL(protocolInfo));
    if (err)
        return false;

    m_client->Connect( iStatus );

    m_state = EConnecting;
    SetActive();
    return true;
}

/*!
    Returns true if this reply has finished; otherwise returns false.
*/
bool QBluetoothTransferReplySymbian::isFinished() const
{
    return m_finished;
}

/*!
    Returns true if this reply is running; otherwise returns false.
*/
bool QBluetoothTransferReplySymbian::isRunning() const
{
    return m_running;
}

void QBluetoothTransferReplySymbian::abort()
{
    qDebug() << "Abort() is not implemented";
}

qint64 QBluetoothTransferReplySymbian::readData(char*, qint64)
{
    return 0;
}

qint64 QBluetoothTransferReplySymbian::writeData(const char*, qint64)
{
    return 0;
}

QBluetoothTransferReply::TransferError QBluetoothTransferReplySymbian::error() const
{
    return NoError;
}

QString QBluetoothTransferReplySymbian::errorString() const
{
    return QString();
}

void QBluetoothTransferReplySymbian::DoCancel()
{
    // Deleting obexclient is the only way to cancel active requests
    if ( m_client ) {
        delete m_client;
        m_client = NULL;
        m_state = EIdle;
    }
}

void QBluetoothTransferReplySymbian::RunL()
{
    switch ( m_state ) {
        case EConnecting:
            m_state = ESending;
            sendObject();
            break;
        case ESending:
            m_state = EDisconnecting;
            disconnect();
            break;
        case EDisconnecting:
            m_state = EIdle;
            m_finished = true;
            m_running = false;
            break;
        case EIdle:
        default:
            break;
    }

}

void QBluetoothTransferReplySymbian::sendObject()
{
    delete m_object;
    m_object = NULL;
    TRAPD(err, m_object = CObexFileObject::NewL());
    if (!err) {
        QFile *file = qobject_cast<QFile *>(m_source);

        TPtrC16 str(reinterpret_cast<const TUint16*>(file->fileName().utf16()));
        TRAPD(error, m_object->InitFromFileL( str ));
        if (!error) {
            m_client->Put( *m_object, iStatus );
            SetActive();
        }
    }
}

void QBluetoothTransferReplySymbian::disconnect()
{
    if ( m_state == ESending ) {
        m_client->Disconnect( iStatus );
        SetActive();
    }
}

#include "moc_qbluetoothtransferreply_symbian_p.cpp"

QTM_END_NAMESPACE
<|endoftext|>


<commit_before>// Time:  O(n^2)
// Space: O(n)

#include <cfloat>
/**
 * Definition for a point.
 * struct Point {
 *     int x;
 *     int y;
 *     Point() : x(0), y(0) {}
 *     Point(int a, int b) : x(a), y(b) {}
 * };
 */
class Solution {
public:
    /**
     * @param points an array of point
     * @return an integer
     */
    int maxPoints(vector<Point>& points) {
        int max_points = 0;
        for (int i = 0; i < points.size(); ++i) {
            unordered_map<double, int> slope_count;
            const auto& start = points[i];
            int same = 1;

            for (int j = i + 1;  j < points.size(); ++j) {
                const auto& end = points[j];
                if (start.x == end.x && start.y == end.y) {
                    ++same;
                } else {
                    double slope = DBL_MAX;
                    if (start.x - end.x != 0) {
                        slope = (start.y - end.y) * 1.0 / (start.x - end.x);
                    }
                    ++slope_count[slope];
                }
            }

            int current_max = same;
            for (const auto& kvp : slope_count) {
                current_max = max(current_max, kvp.second + same);
            }
            max_points = max(max_points, current_max);
        }

        return max_points;
    }
};
<commit_msg>Update max-points-on-a-line.cpp<commit_after>// Time:  O(n^2)
// Space: O(n)

#include <cfloat>
/**
 * Definition for a point.
 * struct Point {
 *     int x;
 *     int y;
 *     Point() : x(0), y(0) {}
 *     Point(int a, int b) : x(a), y(b) {}
 * };
 */
class Solution {
public:
    /**
     * @param points an array of point
     * @return an integer
     */
    int maxPoints(vector<Point>& points) {
        int max_points = 0;
        for (int i = 0; i < points.size(); ++i) {
            unordered_map<double, int> slope_count;
            const auto& start = points[i];
            int same = 1;

            for (int j = i + 1; j < points.size(); ++j) {
                const auto& end = points[j];
                if (start.x == end.x && start.y == end.y) {
                    ++same;
                } else {
                    double slope = DBL_MAX;
                    if (start.x - end.x != 0) {
                        slope = (start.y - end.y) * 1.0 / (start.x - end.x);
                    }
                    ++slope_count[slope];
                }
            }

            int current_max = same;
            for (const auto& kvp : slope_count) {
                current_max = max(current_max, kvp.second + same);
            }
            max_points = max(max_points, current_max);
        }

        return max_points;
    }
};
<|endoftext|>


<commit_before>/**************************************************************************/
/**
**  @file tStorm.cpp
**  @brief Functions for class tStorm.
**
**  A tStorm object generates random storms assuming an exponential
**  distribution of rainfall intensity, storm duration, and time to the
**  next storm. It is essentially an implementation of the model of
**  P. Eagleson, 1978b, Water Resources Research. Its services include
**  reading the necessary parameters from a tInputFile, generating a new
**  storm, and reporting its various values.
**
**  $Id: tStorm.cpp,v 1.26 2003-05-26 17:44:53 childcvs Exp $
*/
/**************************************************************************/

#include <math.h>
#include <string.h>
#include "../Mathutil/mathutil.h"
#include "tStorm.h"
#if !defined(HAVE_NO_NAMESPACE)
# include <iostream>
using namespace std;
#else
# include <iostream.h>
#endif

/**************************************************************************\
**
**  tStorm::tStorm:  Constructor for storms. The default constructor
**                   assigns a value of unity to storm depth, duration,
**                   and interstorm duration. (Note:
**                   this constructor does not allow option for sinusoidal
**                   variation in means).
**
\**************************************************************************/
tStorm::tStorm( bool optvar )
  :
  optVariable(optvar),
  optSinVar(false),
  stdurMean(1.0),
  istdurMean(1.0),
  pMean(1.0),
  p(1.0),
  stdur(1.0),
  istdur(1.0),
  p0(-1.),
  stdur0(-1.),
  istdur0(-1.),
  pdev(-1.),
  stdurdev(-1.),
  istdurdev(-1.),
  twoPiLam(-1.),
  seed(0),      // default seed
  endtm(1.0e9)
{
   //srand( 0 );
}

/**************************************************************************\
**
**  tStorm::tStorm:  The constructor that's really used assigns values for
**                   mean storm depth, duration, and interstorm duration,
**                   initializes current depth, etc, to the mean values,
**                   and initializes the random number generator. (Note:
**                   this constructor does not allow option for sinusoidal
**                   variation in means).
**
\**************************************************************************/
tStorm::tStorm( double mp, double ms, double mis, unsigned sd, bool optvar, double et )
  :
  optVariable(optvar),
  optSinVar(false),
  stdurMean(ms),
  istdurMean(mis),
  pMean(mp),
  p(pMean),
  stdur(stdurMean),
  istdur(istdurMean),
  p0(-1.),
  stdur0(-1.),
  istdur0(-1.),
  pdev(-1.),
  stdurdev(-1.),
  istdurdev(-1.),
  twoPiLam(-1.),
  seed(sd),
  endtm(et)
{
   //srand( seed );
}

/**************************************************************************\
**
**  tStorm::tStorm
**
**  Alternative constructor that reads parameters directly from a tInputFile
**  object. Reads option for variable storms (normally this is "yes"---that's
**  the point of these objects---but a user may wish to switch off variation
**  as a test), mean values for rainfall intensity, duration, and interstorm
**  period, and a random seed to initialize the random number generator.
**    Also reads an option for long-term sinusoidal variations in the mean
**  values, and if the option is selected, reads the relevant parameters.
**  Variables p0, stdur0, and istdur0 are the mean values of the means;
**  pdev, stdurdev, and istdurdev are the range of variation (e.g., if pMean
**  were to fluctuate between 5 and 10, p0 would be 7.5 and pdev 2.5).
**
**  Modifications:
**   - 3/00 initialization now includes creation of ".storm" file for storm
**     history (GT)
**
\**************************************************************************/
tStorm::tStorm( tInputFile &infile )
{
   // Read + set parameters for storm intensity, duration, and spacing
   {
     int tmp_;
     tmp_ = infile.ReadItem( tmp_, "OPTVAR" );
     optVariable = BOOL(tmp_ != 0);
   }
   pMean = infile.ReadItem( pMean, "PMEAN" );
   stdurMean = infile.ReadItem( stdurMean, "STDUR" );
   istdurMean = infile.ReadItem( istdurMean, "ISTDUR" );
   p = pMean;
   stdur = stdurMean;
   istdur = istdurMean;

   endtm = infile.ReadItem( endtm, "RUNTIME" );
   double help;

   help = infile.ReadItem( help, "OPTREADINPUT" );
   if(help>0){
      help = infile.ReadItem( help, "INPUTTIME" );
      endtm += help;
   }

   // Handle option for sinuidoil variation in means
   {
     int tmp_;
     tmp_ = infile.ReadItem( tmp_, "OPTSINVAR" );
     optSinVar = BOOL(tmp_ != 0);
   }
   if( optSinVar )
   {
      p0 = pMean;
      stdur0 = stdurMean;
      istdur0 = istdurMean;
      twoPiLam = (2.0*PI)/(infile.ReadItem( twoPiLam, "PERIOD" ));
      pdev = infile.ReadItem( pdev, "MAXPMEAN" ) - pMean;
      if( pdev<0 ) cerr << "Warning: MAXPMEAN < PMEAN !";
      else if( pdev > pMean ) cerr << "Warning: MINPMEAN < 0 !";
      stdurdev = infile.ReadItem( stdurdev, "MAXSTDURMN" ) - stdurMean;
      if( stdurdev<0 ) cerr << "Warning: MAXSTDURMN < STDURMN !";
      else if( stdurdev > stdurMean ) cerr << "Warning: MINSTDURMN < 0 !";
      istdurdev = infile.ReadItem( istdurdev, "MAXISTDURMN" ) - istdurMean;
      if( istdurdev<0 ) cerr << "Warning: MAXISTDURMN < ISTDURMN !";
      else if( istdurdev > istdurMean ) cerr << "Warning: MINISTDURMN < 0 !";
   }

   // If variable storms used, create a file for writing them
   if( optVariable )
   {
      char fname[87];
      infile.ReadItem( fname, "OUTFILENAME" );
      strcat( fname, ".storm" );
      stormfile.open( fname );
      if( !stormfile.good() )
          cerr << "Warning: unable to create storm data file '"
               << fname << "'\n";
   }

   // Read and initialize seed for random number generation
   seed = infile.ReadItem( seed, "SEED" );
   //srand( seed );
}

/**************************************************************************\
**
**  tStorm::GenerateStorm
**
**  Generates a new storm by drawing new values of p, stdur, and istdur from
**  an exponential distribution and updating the random seed.
**    If the minp parameter is greater than zero, the function will keep
**  picking storms until it finds one with p>minp. The total elapsed time,
**  including the rejected storms and their associated interstorm periods,
**  is stored istdur.
**
**  Inputs:      minp -- minimum value of rainfall rate p (default 0)
**               mind -- minimum storm depth to produce runoff (default 0)
**               tm -- current time in simulation
**  Members updated:  p, stdur, istdur take on new random values (if optVar)
**                    pMean, stdurMean, istdurMean adjusted (if optSinVar)
**  Assumptions:  pMean > 0
**
**  Modifications:
**   - changed AND to OR in while loop, GT 5/99
**   - added to while loop an additional check to see if time has run out,
**     NG 2/00
**   - added output of time, storm intensity, & duration to ".storm" file
**     GT 3/00
**
\**************************************************************************/
void tStorm::GenerateStorm( double tm, double minp, double mind )
{
   // If option for sinusoidal variation is on, adjust the means
   // Also set values for current storm to the means, in case option for
   // random storms is off.
   if( optSinVar )
   {
      double sinfn = sin( tm*twoPiLam );
      pMean = p0 + pdev*sinfn;
      //cout << "pMean = " << pMean << endl;
      stdurMean = stdur0 + stdurdev*sinfn;
      istdurMean = istdur0 + istdurdev*sinfn;
      p = pMean;
      stdur = stdurMean;
      istdur = istdurMean;
   }

   // If option for random storms is on, pick a storm at random.
   // Keep picking and accumulating time until the storm depth or intensity
   // is greater than the minimum value needed to produce runoff.

   if( optVariable )
   {
      stdur = 0;
      istdur = 0;
      do
      {
         p = pMean*ExpDev( &seed );
         istdur += istdurMean*ExpDev( &seed ) + stdur;
         stdur = stdurMean*ExpDev( &seed );
         //cout << "P " << p << "  ST " << stdur << "  IST " << istdur
         //     << "  DP " << p*stdur << " minp " << minp << " mind " <<mind <<
         //            endl;
         //srand( seed );
      } while( (p<=minp || (p*stdur)<=mind) && (tm+istdur+stdur<endtm) );
      stormfile << istdur << " " << p << " " << stdur << endl;
   }
}

/**************************************************************************\
**
**  tStorm::ExpDev:  Finds a random number with an exponential distribution
**                   (adapted from Numerical Recipes).
**
\**************************************************************************/
double tStorm::ExpDev( long *idum ) const
{
    double dum;

    do
        dum = ran3( idum );
    while( dum==0.0 );
    return -log(dum);
}

/**************************************************************************\
**
**  tStorm "get" routines: return various variables
**
\**************************************************************************/

double tStorm::getStormDuration() const { return stdur; }
double tStorm::interstormDur() const { return istdur; }
double tStorm::getRainrate() const { return p; }
double tStorm::getMeanStormDur() const {return stdurMean;}
double tStorm::getMeanInterstormDur() const {return istdurMean;}
double tStorm::getMeanPrecip() const {return pMean;}

/**************************************************************************\
**
**  GammaDev
**
**  Returns a random variable drawn from a Gamma distribution with parameter m.
**
**  (Note: not actually called; provided for future use).
**
\**************************************************************************/
double tStorm::GammaDev(double m, long * idum) const
{
  double x, y,z, c,t,b,u,w,v;

  if (m<1)
    {
      c = 1/m;
      t = 0.07 + 0.75*sqrt(1-m);
      b = 1 + exp(-t)*m/t;
      int accept = 0;
      while (accept == 0)
        {
          u = ran3(idum);
          w = ran3(idum);
          v = b *u;
          if (v<=1)
            {
              x  = t * pow(v, c);
              accept = ((w<=((2-x)/(2+x))) || (w<=exp(-x)));
            }
          else
            {
              x = -log(c*t*(b-v));
              y = x/t;
              accept = (((w*(m + y - m*y)) <= 1) || (w<= ( pow(y, (m-1)))));
            }
        }
    }
  else
    {
      b = m-1;
      c = 3*m - 0.75;
      int accept = 0;
      while (accept == 0)
        {
          u = ran3(idum); v = ran3(idum);
          w = u* ( 1-u);
          y = sqrt(c/w) * (u - 0.5);
          x = b + y;
          if ( x>= 0)
            {
              z = 64*( pow(w,3.))*v*v;
              accept = (z <= ( 1 - 2*y*y/x)) || ( log(z) <= (2*(b*log(x/b) - y)));
            }
        }
    }
  return x;
}

<commit_msg>debug only<commit_after>/**************************************************************************/
/**
**  @file tStorm.cpp
**  @brief Functions for class tStorm.
**
**  A tStorm object generates random storms assuming an exponential
**  distribution of rainfall intensity, storm duration, and time to the
**  next storm. It is essentially an implementation of the model of
**  P. Eagleson, 1978b, Water Resources Research. Its services include
**  reading the necessary parameters from a tInputFile, generating a new
**  storm, and reporting its various values.
**
**  $Id: tStorm.cpp,v 1.27 2003-07-15 16:01:17 childcvs Exp $
*/
/**************************************************************************/

#include <math.h>
#include <string.h>
#include "../Mathutil/mathutil.h"
#include "tStorm.h"
#if !defined(HAVE_NO_NAMESPACE)
# include <iostream>
using namespace std;
#else
# include <iostream.h>
#endif

/**************************************************************************\
**
**  tStorm::tStorm:  Constructor for storms. The default constructor
**                   assigns a value of unity to storm depth, duration,
**                   and interstorm duration. (Note:
**                   this constructor does not allow option for sinusoidal
**                   variation in means).
**
\**************************************************************************/
tStorm::tStorm( bool optvar )
  :
  optVariable(optvar),
  optSinVar(false),
  stdurMean(1.0),
  istdurMean(1.0),
  pMean(1.0),
  p(1.0),
  stdur(1.0),
  istdur(1.0),
  p0(-1.),
  stdur0(-1.),
  istdur0(-1.),
  pdev(-1.),
  stdurdev(-1.),
  istdurdev(-1.),
  twoPiLam(-1.),
  seed(0),      // default seed
  endtm(1.0e9)
{
   //srand( 0 );
}

/**************************************************************************\
**
**  tStorm::tStorm:  The constructor that's really used assigns values for
**                   mean storm depth, duration, and interstorm duration,
**                   initializes current depth, etc, to the mean values,
**                   and initializes the random number generator. (Note:
**                   this constructor does not allow option for sinusoidal
**                   variation in means).
**
\**************************************************************************/
tStorm::tStorm( double mp, double ms, double mis, unsigned sd, bool optvar, double et )
  :
  optVariable(optvar),
  optSinVar(false),
  stdurMean(ms),
  istdurMean(mis),
  pMean(mp),
  p(pMean),
  stdur(stdurMean),
  istdur(istdurMean),
  p0(-1.),
  stdur0(-1.),
  istdur0(-1.),
  pdev(-1.),
  stdurdev(-1.),
  istdurdev(-1.),
  twoPiLam(-1.),
  seed(sd),
  endtm(et)
{
   //srand( seed );
}

/**************************************************************************\
**
**  tStorm::tStorm
**
**  Alternative constructor that reads parameters directly from a tInputFile
**  object. Reads option for variable storms (normally this is "yes"---that's
**  the point of these objects---but a user may wish to switch off variation
**  as a test), mean values for rainfall intensity, duration, and interstorm
**  period, and a random seed to initialize the random number generator.
**    Also reads an option for long-term sinusoidal variations in the mean
**  values, and if the option is selected, reads the relevant parameters.
**  Variables p0, stdur0, and istdur0 are the mean values of the means;
**  pdev, stdurdev, and istdurdev are the range of variation (e.g., if pMean
**  were to fluctuate between 5 and 10, p0 would be 7.5 and pdev 2.5).
**
**  Modifications:
**   - 3/00 initialization now includes creation of ".storm" file for storm
**     history (GT)
**
\**************************************************************************/
tStorm::tStorm( tInputFile &infile )
{
   // Read + set parameters for storm intensity, duration, and spacing
   {
     int tmp_;
     tmp_ = infile.ReadItem( tmp_, "OPTVAR" );
     optVariable = BOOL(tmp_ != 0);
   }
   pMean = infile.ReadItem( pMean, "PMEAN" );
   stdurMean = infile.ReadItem( stdurMean, "STDUR" );
   istdurMean = infile.ReadItem( istdurMean, "ISTDUR" );
   p = pMean;
   stdur = stdurMean;
   istdur = istdurMean;

   endtm = infile.ReadItem( endtm, "RUNTIME" );
   double help;

   help = infile.ReadItem( help, "OPTREADINPUT" );
   if(help>0){
      help = infile.ReadItem( help, "INPUTTIME" );
      endtm += help;
   }

   // Handle option for sinuidoil variation in means
   {
     int tmp_;
     tmp_ = infile.ReadItem( tmp_, "OPTSINVAR" );
     optSinVar = BOOL(tmp_ != 0);
   }
   if( optSinVar )
   {
      p0 = pMean;
      stdur0 = stdurMean;
      istdur0 = istdurMean;
      twoPiLam = (2.0*PI)/(infile.ReadItem( twoPiLam, "PERIOD" ));
      pdev = infile.ReadItem( pdev, "MAXPMEAN" ) - pMean;
      if( pdev<0 ) cerr << "Warning: MAXPMEAN < PMEAN !";
      else if( pdev > pMean ) cerr << "Warning: MINPMEAN < 0 !";
      stdurdev = infile.ReadItem( stdurdev, "MAXSTDURMN" ) - stdurMean;
      if( stdurdev<0 ) cerr << "Warning: MAXSTDURMN < STDURMN !";
      else if( stdurdev > stdurMean ) cerr << "Warning: MINSTDURMN < 0 !";
      istdurdev = infile.ReadItem( istdurdev, "MAXISTDURMN" ) - istdurMean;
      if( istdurdev<0 ) cerr << "Warning: MAXISTDURMN < ISTDURMN !";
      else if( istdurdev > istdurMean ) cerr << "Warning: MINISTDURMN < 0 !";
   }

   // If variable storms used, create a file for writing them
   if( optVariable )
   {
      char fname[87];
      infile.ReadItem( fname, "OUTFILENAME" );
      strcat( fname, ".storm" );
      stormfile.open( fname );
      if( !stormfile.good() )
          cerr << "Warning: unable to create storm data file '"
               << fname << "'\n";
   }

   // Read and initialize seed for random number generation
   seed = infile.ReadItem( seed, "SEED" );
   //srand( seed );
}

/**************************************************************************\
**
**  tStorm::GenerateStorm
**
**  Generates a new storm by drawing new values of p, stdur, and istdur from
**  an exponential distribution and updating the random seed.
**    If the minp parameter is greater than zero, the function will keep
**  picking storms until it finds one with p>minp. The total elapsed time,
**  including the rejected storms and their associated interstorm periods,
**  is stored istdur.
**
**  Inputs:      minp -- minimum value of rainfall rate p (default 0)
**               mind -- minimum storm depth to produce runoff (default 0)
**               tm -- current time in simulation
**  Members updated:  p, stdur, istdur take on new random values (if optVar)
**                    pMean, stdurMean, istdurMean adjusted (if optSinVar)
**  Assumptions:  pMean > 0
**
**  Modifications:
**   - changed AND to OR in while loop, GT 5/99
**   - added to while loop an additional check to see if time has run out,
**     NG 2/00
**   - added output of time, storm intensity, & duration to ".storm" file
**     GT 3/00
**
\**************************************************************************/
void tStorm::GenerateStorm( double tm, double minp, double mind )
{
   // If option for sinusoidal variation is on, adjust the means
   // Also set values for current storm to the means, in case option for
   // random storms is off.
   if( optSinVar )
   {
      double sinfn = sin( tm*twoPiLam );
      pMean = p0 + pdev*sinfn;
      //cout << "pMean = " << pMean << endl;
      stdurMean = stdur0 + stdurdev*sinfn;
      istdurMean = istdur0 + istdurdev*sinfn;
      p = pMean;
      stdur = stdurMean;
      istdur = istdurMean;
   }

   // If option for random storms is on, pick a storm at random.
   // Keep picking and accumulating time until the storm depth or intensity
   // is greater than the minimum value needed to produce runoff.

   if( optVariable )
   {
      stdur = 0;
      istdur = 0;
      do
      {
         p = pMean*ExpDev( &seed );
         istdur += istdurMean*ExpDev( &seed ) + stdur;
         stdur = stdurMean*ExpDev( &seed );
	 if(0) { // Debug
	   cout << "P " << p << "  ST " << stdur << "  IST " << istdur
		<< "  DP " << p*stdur << " minp " << minp << " mind " <<mind <<
	     endl;
	 }
         //srand( seed );
      } while( (p<=minp || (p*stdur)<=mind) && (tm+istdur+stdur<endtm) );
      stormfile << istdur << " " << p << " " << stdur << endl;
   }
}

/**************************************************************************\
**
**  tStorm::ExpDev:  Finds a random number with an exponential distribution
**                   (adapted from Numerical Recipes).
**
\**************************************************************************/
double tStorm::ExpDev( long *idum ) const
{
    double dum;

    do
        dum = ran3( idum );
    while( dum==0.0 );
    return -log(dum);
}

/**************************************************************************\
**
**  tStorm "get" routines: return various variables
**
\**************************************************************************/

double tStorm::getStormDuration() const { return stdur; }
double tStorm::interstormDur() const { return istdur; }
double tStorm::getRainrate() const { return p; }
double tStorm::getMeanStormDur() const {return stdurMean;}
double tStorm::getMeanInterstormDur() const {return istdurMean;}
double tStorm::getMeanPrecip() const {return pMean;}

/**************************************************************************\
**
**  GammaDev
**
**  Returns a random variable drawn from a Gamma distribution with parameter m.
**
**  (Note: not actually called; provided for future use).
**
\**************************************************************************/
double tStorm::GammaDev(double m, long * idum) const
{
  double x, y,z, c,t,b,u,w,v;

  if (m<1)
    {
      c = 1/m;
      t = 0.07 + 0.75*sqrt(1-m);
      b = 1 + exp(-t)*m/t;
      int accept = 0;
      while (accept == 0)
        {
          u = ran3(idum);
          w = ran3(idum);
          v = b *u;
          if (v<=1)
            {
              x  = t * pow(v, c);
              accept = ((w<=((2-x)/(2+x))) || (w<=exp(-x)));
            }
          else
            {
              x = -log(c*t*(b-v));
              y = x/t;
              accept = (((w*(m + y - m*y)) <= 1) || (w<= ( pow(y, (m-1)))));
            }
        }
    }
  else
    {
      b = m-1;
      c = 3*m - 0.75;
      int accept = 0;
      while (accept == 0)
        {
          u = ran3(idum); v = ran3(idum);
          w = u* ( 1-u);
          y = sqrt(c/w) * (u - 0.5);
          x = b + y;
          if ( x>= 0)
            {
              z = 64*( pow(w,3.))*v*v;
              accept = (z <= ( 1 - 2*y*y/x)) || ( log(z) <= (2*(b*log(x/b) - y)));
            }
        }
    }
  return x;
}

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkTimeStamp.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

  Portions of this code are covered under the VTK copyright.
  See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "itkTimeStamp.h"
#include "itkFastMutexLock.h"
#if defined(__APPLE__)
  #include <libkern/OSAtomic.h>
#endif

namespace itk
{

/**
 * Instance creation.
 */
TimeStamp*
TimeStamp
::New()
{
  return new Self;
}

/**
 * Make sure the new time stamp is greater than all others so far.
 */
void
TimeStamp
::Modified()
{
// Windows optimization
#if defined(WIN32) || defined(_WIN32)
  static LONG itkTimeStampTime = 0;
  this->ModifiedTime = (unsigned long)InterlockedIncrement(&itkTimeStampTime);

// Mac optimization (64 bit)
#elif defined(__APPLE__) && __LP64__
  // "m_ModifiedTime" is "unsigned long", a type that changess sizes
  // depending on architecture.  The atomic increment is safe, since it
  // operates on a variable of the exact type needed.  The cast does not
  // change the size, but does change signedness, which is not ideal.
  static volatile int64_t itkTimeStampTime = 0;
  m_ModifiedTime = (unsigned long)OSAtomicIncrement64Barrier(&itkTimeStampTime);

// Mac optimization (32 bit, 10.4 or later)
#elif defined(__APPLE__) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1040)
  static volatile int32_t itkTimeStampTime = 0;
  m_ModifiedTime = (unsigned long)OSAtomicIncrement32Barrier(&itkTimeStampTime);

// General case
#else
  /**
   * Initialize static member
   */
  static unsigned long itkTimeStampTime = 0;

  /** Used for mutex locking */
  static SimpleFastMutexLock TimeStampMutex;

  TimeStampMutex.Lock();
  m_ModifiedTime = ++itkTimeStampTime;
  TimeStampMutex.Unlock();
#endif

}

} // end namespace itk
<commit_msg>COMP: fixed embarassing copy-paste bug that broke the build<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkTimeStamp.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

  Portions of this code are covered under the VTK copyright.
  See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "itkTimeStamp.h"
#include "itkFastMutexLock.h"
#if defined(__APPLE__)
  #include <libkern/OSAtomic.h>
#endif

namespace itk
{

/**
 * Instance creation.
 */
TimeStamp*
TimeStamp
::New()
{
  return new Self;
}

/**
 * Make sure the new time stamp is greater than all others so far.
 */
void
TimeStamp
::Modified()
{
// Windows optimization
#if defined(WIN32) || defined(_WIN32)
  static LONG itkTimeStampTime = 0;
  m_ModifiedTime = (unsigned long)InterlockedIncrement(&itkTimeStampTime);

// Mac optimization (64 bit)
#elif defined(__APPLE__) && __LP64__
  // "m_ModifiedTime" is "unsigned long", a type that changess sizes
  // depending on architecture.  The atomic increment is safe, since it
  // operates on a variable of the exact type needed.  The cast does not
  // change the size, but does change signedness, which is not ideal.
  static volatile int64_t itkTimeStampTime = 0;
  m_ModifiedTime = (unsigned long)OSAtomicIncrement64Barrier(&itkTimeStampTime);

// Mac optimization (32 bit, 10.4 or later)
#elif defined(__APPLE__) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1040)
  static volatile int32_t itkTimeStampTime = 0;
  m_ModifiedTime = (unsigned long)OSAtomicIncrement32Barrier(&itkTimeStampTime);

// General case
#else
  /**
   * Initialize static member
   */
  static unsigned long itkTimeStampTime = 0;

  /** Used for mutex locking */
  static SimpleFastMutexLock TimeStampMutex;

  TimeStampMutex.Lock();
  m_ModifiedTime = ++itkTimeStampTime;
  TimeStampMutex.Unlock();
#endif

}

} // end namespace itk
<|endoftext|>


<commit_before>#ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__DISCRETE__BERNOULLI_HPP__
#define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__DISCRETE__BERNOULLI_HPP__

#include <stan/agrad.hpp>
#include <stan/math/error_handling.hpp>
#include <stan/math/special_functions.hpp>
#include <stan/meta/traits.hpp>
#include <stan/prob/traits.hpp>
#include <stan/prob/constants.hpp>

namespace stan {

  namespace prob {

    // Bernoulli(n|theta)   [0 <= n <= 1;   0 <= theta <= 1]
    // FIXME: documentation
    template <bool propto,
              typename T_n, typename T_prob,
              class Policy>
    typename return_type<T_prob>::type
    bernoulli_log(const T_n& n,
                  const T_prob& theta,
                  const Policy&) {
      static const char* function = "stan::prob::bernoulli_log(%1%)";

      using stan::math::check_finite;
      using stan::math::check_bounded;
      using stan::math::log1m;
      using stan::math::value_of;
      using stan::math::check_consistent_sizes;
      using stan::prob::include_summand;

      // check if any vectors are zero length
      if (!(stan::length(n)
	    && stan::length(theta)))
	return 0.0;

      // set up return value accumulator
      double logp(0.0);

      // validate args (here done over var, which should be OK)
      if (!check_bounded(function, n, 0, 1, "n", &logp, Policy()))
        return logp;
      if (!check_finite(function, theta, "Probability parameter", &logp, Policy()))
        return logp;
      if (!check_bounded(function, theta, 0.0, 1.0,
                         "Probability parameter", &logp, Policy()))
        return logp;
      if (!(check_consistent_sizes(function,
                                   n,theta,
				   "Random variable","Probability parameter",
                                   &logp, Policy())))
        return logp;

      // check if no variables are involved and prop-to
      if (!include_summand<propto,T_prob>::value)
	return 0.0;

      // set up template expressions wrapping scalars into vector views
      VectorView<const T_n> n_vec(n);
      VectorView<const T_prob> theta_vec(theta);
      size_t N = max_size(n, theta);
      agrad::OperandsAndPartials<T_prob> operands_and_partials(theta);

      if (length(theta) == 1) {
	size_t sum = 0;
	for (size_t n = 0; n < N; n++) {
	  sum += value_of(n_vec[n]);
	}
	const double theta_dbl = value_of(theta_vec[0]);
	const double log_theta = log(theta_dbl);
	const double log1m_theta = log1m(theta_dbl);
	if (include_summand<propto,T_prob>::value) {
	  logp += sum * log_theta;
	  logp += (N - sum) * log1m_theta;

	  operands_and_partials.d_x1[0] += sum / theta_dbl;
	  operands_and_partials.d_x1[0] += (N - sum) / (theta_dbl - 1);
	}
      } else {
	for (size_t n = 0; n < N; n++) {
	  // pull out values of arguments
	  const int n_int = value_of(n_vec[n]);
	  const double theta_dbl = value_of(theta_vec[n]);

	  if (include_summand<propto,T_prob>::value) {
	    if (n_int == 1)
	      logp += log(theta_dbl);
	    else
	      logp += log1m(theta_dbl);
	  }

	  // gradient
	  if (include_summand<propto,T_prob>::value) {
	    if (n_int == 1)
	      operands_and_partials.d_x1[n] += 1.0 / theta_dbl;
	    else
	      operands_and_partials.d_x1[n] += 1.0 / (theta_dbl - 1);
	  }
	}
      }
      return operands_and_partials.to_var(logp);
    }

    template <bool propto,
	      typename T_y,
              typename T_prob>
    inline
    typename return_type<T_prob>::type
    bernoulli_log(const T_y& n,
                  const T_prob& theta) {
      return bernoulli_log<propto>(n,theta,stan::math::default_policy());
    }

    template <typename T_y,
	      typename T_prob,
              class Policy>
    inline
    typename return_type<T_prob>::type
    bernoulli_log(const T_y& n,
                  const T_prob& theta,
                  const Policy&) {
      return bernoulli_log<false>(n,theta,Policy());
    }

    template <typename T_y, typename T_prob>
    inline
    typename return_type<T_prob>::type
    bernoulli_log(const T_y& n,
                  const T_prob& theta) {
      return bernoulli_log<false>(n,theta,stan::math::default_policy());
    }

    // Bernoulli(n|inv_logit(theta))   [0 <= n <= 1;   -inf <= theta <= inf]
    // FIXME: documentation
    template <bool propto,
	      typename T_n,
              typename T_prob,
              class Policy>
    typename return_type<T_prob>::type
    bernoulli_logit_log(const T_n& n,
                        const T_prob& theta,
                        const Policy&) {
      static const char* function = "stan::prob::bernoulli_logit_log(%1%)";

      using stan::is_constant_struct;
      using stan::math::check_not_nan;
      using stan::math::check_bounded;
      using stan::math::value_of;
      using stan::math::check_consistent_sizes;
      using stan::prob::include_summand;
      using stan::math::log1p;
      using stan::math::inv_logit;

      // check if any vectors are zero length
      if (!(stan::length(n)
	    && stan::length(theta)))
	return 0.0;

      // set up return value accumulator
      double logp(0.0);

      // validate args (here done over var, which should be OK)
      if (!check_bounded(function, n, 0, 1, "n", &logp, Policy()))
        return logp;
      if (!check_not_nan(function, theta, "Logit transformed probability parameter",
                         &logp, Policy()))
        return logp;
      if (!(check_consistent_sizes(function,
                                   n,theta,
				   "Random variable","Probability parameter",
                                   &logp, Policy())))
	return logp;

      // check if no variables are involved and prop-to
      if (!include_summand<propto,T_prob>::value)
	return 0.0;

      // set up template expressions wrapping scalars into vector views
      VectorView<const T_n> n_vec(n);
      VectorView<const T_prob> theta_vec(theta);
      size_t N = max_size(n, theta);
      agrad::OperandsAndPartials<T_prob> operands_and_partials(theta);

      for (size_t n = 0; n < N; n++) {
	// pull out values of arguments
	const int n_int = value_of(n_vec[n]);
	const double theta_dbl = value_of(theta_vec[n]);

	// reusable subexpression values
	const int sign = 2*n_int-1;
	const double ntheta = sign * theta_dbl;
	const double exp_m_ntheta = exp(-ntheta);

	if (include_summand<propto,T_prob>::value) {
	  // Handle extreme values gracefully using Taylor approximations.
	  const static double cutoff = 20.0;
	  if (ntheta > cutoff)
	    logp -= exp_m_ntheta;
	  else if (ntheta < -cutoff)
	    logp += ntheta;
	  else
	    logp -= log1p(exp_m_ntheta);
	}

	// gradients
	if (!is_constant_struct<T_prob>::value) {
	  const static double cutoff = 20.0;
	  if (ntheta > cutoff)
	    operands_and_partials.d_x1[n] -= exp_m_ntheta;
	  else if (ntheta < -cutoff)
	    operands_and_partials.d_x1[n] += sign;
	  else
	    operands_and_partials.d_x1[n] += sign * exp_m_ntheta / (exp_m_ntheta + 1);
	}
      }
      return operands_and_partials.to_var(logp);
    }

    template <bool propto,
	      typename T_n,
              typename T_prob>
    inline
    typename return_type<T_prob>::type
    bernoulli_logit_log(const T_n& n,
                        const T_prob& theta) {
      return bernoulli_logit_log<propto>(n,theta,stan::math::default_policy());
    }

    template <typename T_n,
	      typename T_prob,
              class Policy>
    inline
    typename return_type<T_prob>::type
    bernoulli_logit_log(const T_n& n,
                        const T_prob& theta,
                        const Policy&) {
      return bernoulli_logit_log<false>(n,theta,Policy());
    }

    template <typename T_n,
	      typename T_prob>
    inline
    typename return_type<T_prob>::type
    bernoulli_logit_log(const T_n& n,
                        const T_prob& theta) {
      return bernoulli_logit_log<false>(n,theta,stan::math::default_policy());
    }

      // Bernoulli CDF
      template <bool propto, typename T_n, typename T_prob, class Policy>
      typename return_type<T_prob>::type
      bernoulli_cdf(const T_n& n, const T_prob& theta, const Policy&) {

          static const char* function = "stan::prob::bernoulli_cdf(%1%)";

          using stan::math::check_finite;
          using stan::math::check_bounded;
          using stan::math::check_consistent_sizes;
          using stan::prob::include_summand;

          // Ensure non-zero argument lenghts
          if (!(stan::length(n) && stan::length(theta)))
              return 0.0;

          double P(1.0);

          // Validate arguments
          if (!check_bounded(function, n, 0, 1, "n", &P, Policy()))
              return P;

          if (!check_finite(function, theta, "Probability parameter", &P, Policy()))
              return P;

          if (!check_bounded(function, theta, 0.0, 1.0,
                             "Probability parameter", &P, Policy()))
              return P;

          if (!(check_consistent_sizes(function,
                                       n, theta,
                                       "Random variable","Probability parameter",
                                       &P, Policy())))
              return P;

          // Return if everything is constant and only proportionality is required
          if (!include_summand<propto,T_prob>::value)
              return 0.0;

          // set up template expressions wrapping scalars into vector views
          VectorView<const T_n> n_vec(n);
          VectorView<const T_prob> theta_vec(theta);
          size_t size = max_size(n, theta);

          // Compute vectorized CDF and gradient
          using stan::math::value_of;
          using boost::math::ibetac;
          using boost::math::ibeta_derivative;

          agrad::OperandsAndPartials<T_prob> operands_and_partials(theta);

          for (size_t i = 0; i < size; i++) {

              const double n_dbl = value_of(n_vec[i]);
              const double theta_dbl = value_of(theta_vec[i]);

              const double Pi = ibetac(n_dbl + 1, 1 - n_dbl, theta_dbl);

              P *= Pi;

              if (!is_constant_struct<T_prob>::value)
                  operands_and_partials.d_x1[i] += - ibeta_derivative(n_dbl + 1, 1 - n_dbl, theta_dbl) / Pi;

          }

          for (size_t i = 0; i < size; i++) {

              if (!is_constant_struct<T_prob>::value)
                  operands_and_partials.d_x1[i] *= P;

          }

          return P;

      }

      template <bool propto, typename T_y, typename T_prob>
      inline typename return_type<T_prob>::type
      bernoulli_cdf(const T_y& n, const T_prob& theta) {
          return bernoulli_log<propto>(n, theta, stan::math::default_policy());
      }

      template <typename T_y, typename T_prob, class Policy>
      inline typename return_type<T_prob>::type
      bernoulli_cdf(const T_y& n, const T_prob& theta, const Policy&) {
          return bernoulli_cdf<false>(n, theta, Policy());
      }

      template <typename T_y, typename T_prob>
      inline typename return_type<T_prob>::type
      bernoulli_cdf(const T_y& n, const T_prob& theta) {
          return bernoulli_cdf<false>(n, theta, stan::math::default_policy());
      }

  }
}
#endif
<commit_msg>Fixed 0*log(0)=nan issue in bernoulli_log() when theta = 0 or 1.<commit_after>#ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__DISCRETE__BERNOULLI_HPP__
#define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__DISCRETE__BERNOULLI_HPP__

#include <stan/agrad.hpp>
#include <stan/math/error_handling.hpp>
#include <stan/math/special_functions.hpp>
#include <stan/meta/traits.hpp>
#include <stan/prob/traits.hpp>
#include <stan/prob/constants.hpp>

namespace stan {

  namespace prob {

    // Bernoulli(n|theta)   [0 <= n <= 1;   0 <= theta <= 1]
    // FIXME: documentation
    template <bool propto,
              typename T_n, typename T_prob,
              class Policy>
    typename return_type<T_prob>::type
    bernoulli_log(const T_n& n,
                  const T_prob& theta,
                  const Policy&) {
      static const char* function = "stan::prob::bernoulli_log(%1%)";

      using stan::math::check_finite;
      using stan::math::check_bounded;
      using stan::math::log1m;
      using stan::math::value_of;
      using stan::math::check_consistent_sizes;
      using stan::prob::include_summand;

      // check if any vectors are zero length
      if (!(stan::length(n)
	    && stan::length(theta)))
	return 0.0;

      // set up return value accumulator
      double logp(0.0);

      // validate args (here done over var, which should be OK)
      if (!check_bounded(function, n, 0, 1, "n", &logp, Policy()))
        return logp;
      if (!check_finite(function, theta, "Probability parameter", &logp, Policy()))
        return logp;
      if (!check_bounded(function, theta, 0.0, 1.0,
                         "Probability parameter", &logp, Policy()))
        return logp;
      if (!(check_consistent_sizes(function,
                                   n,theta,
				   "Random variable","Probability parameter",
                                   &logp, Policy())))
        return logp;

      // check if no variables are involved and prop-to
      if (!include_summand<propto,T_prob>::value)
	return 0.0;

      // set up template expressions wrapping scalars into vector views
      VectorView<const T_n> n_vec(n);
      VectorView<const T_prob> theta_vec(theta);
      size_t N = max_size(n, theta);
      agrad::OperandsAndPartials<T_prob> operands_and_partials(theta);

      if (length(theta) == 1) {
	size_t sum = 0;
	for (size_t n = 0; n < N; n++) {
	  sum += value_of(n_vec[n]);
	}
        const double theta_dbl = value_of(theta_vec[0]);
        // avoid nans when sum == N or sum == 0
        if (sum == N) {
          logp += N * log(theta_dbl);
          operands_and_partials.d_x1[0] += N / theta_dbl;
        } else if (sum == 0) {
          logp += N * log1m(theta_dbl);
          operands_and_partials.d_x1[0] += N / (theta_dbl - 1);
        } else {
          const double log_theta = log(theta_dbl);
          const double log1m_theta = log1m(theta_dbl);
          if (include_summand<propto,T_prob>::value) {
            logp += sum * log_theta;
            logp += (N - sum) * log1m_theta;

            operands_and_partials.d_x1[0] += sum / theta_dbl;
            operands_and_partials.d_x1[0] += (N - sum) / (theta_dbl - 1);
          }
        }
      } else {
	for (size_t n = 0; n < N; n++) {
	  // pull out values of arguments
	  const int n_int = value_of(n_vec[n]);
	  const double theta_dbl = value_of(theta_vec[n]);

	  if (include_summand<propto,T_prob>::value) {
	    if (n_int == 1)
	      logp += log(theta_dbl);
	    else
	      logp += log1m(theta_dbl);
	  }

	  // gradient
	  if (include_summand<propto,T_prob>::value) {
	    if (n_int == 1)
	      operands_and_partials.d_x1[n] += 1.0 / theta_dbl;
	    else
	      operands_and_partials.d_x1[n] += 1.0 / (theta_dbl - 1);
	  }
	}
      }
      return operands_and_partials.to_var(logp);
    }

    template <bool propto,
	      typename T_y,
              typename T_prob>
    inline
    typename return_type<T_prob>::type
    bernoulli_log(const T_y& n,
                  const T_prob& theta) {
      return bernoulli_log<propto>(n,theta,stan::math::default_policy());
    }

    template <typename T_y,
	      typename T_prob,
              class Policy>
    inline
    typename return_type<T_prob>::type
    bernoulli_log(const T_y& n,
                  const T_prob& theta,
                  const Policy&) {
      return bernoulli_log<false>(n,theta,Policy());
    }

    template <typename T_y, typename T_prob>
    inline
    typename return_type<T_prob>::type
    bernoulli_log(const T_y& n,
                  const T_prob& theta) {
      return bernoulli_log<false>(n,theta,stan::math::default_policy());
    }

    // Bernoulli(n|inv_logit(theta))   [0 <= n <= 1;   -inf <= theta <= inf]
    // FIXME: documentation
    template <bool propto,
	      typename T_n,
              typename T_prob,
              class Policy>
    typename return_type<T_prob>::type
    bernoulli_logit_log(const T_n& n,
                        const T_prob& theta,
                        const Policy&) {
      static const char* function = "stan::prob::bernoulli_logit_log(%1%)";

      using stan::is_constant_struct;
      using stan::math::check_not_nan;
      using stan::math::check_bounded;
      using stan::math::value_of;
      using stan::math::check_consistent_sizes;
      using stan::prob::include_summand;
      using stan::math::log1p;
      using stan::math::inv_logit;

      // check if any vectors are zero length
      if (!(stan::length(n)
	    && stan::length(theta)))
	return 0.0;

      // set up return value accumulator
      double logp(0.0);

      // validate args (here done over var, which should be OK)
      if (!check_bounded(function, n, 0, 1, "n", &logp, Policy()))
        return logp;
      if (!check_not_nan(function, theta, "Logit transformed probability parameter",
                         &logp, Policy()))
        return logp;
      if (!(check_consistent_sizes(function,
                                   n,theta,
				   "Random variable","Probability parameter",
                                   &logp, Policy())))
	return logp;

      // check if no variables are involved and prop-to
      if (!include_summand<propto,T_prob>::value)
	return 0.0;

      // set up template expressions wrapping scalars into vector views
      VectorView<const T_n> n_vec(n);
      VectorView<const T_prob> theta_vec(theta);
      size_t N = max_size(n, theta);
      agrad::OperandsAndPartials<T_prob> operands_and_partials(theta);

      for (size_t n = 0; n < N; n++) {
	// pull out values of arguments
	const int n_int = value_of(n_vec[n]);
	const double theta_dbl = value_of(theta_vec[n]);

	// reusable subexpression values
	const int sign = 2*n_int-1;
	const double ntheta = sign * theta_dbl;
	const double exp_m_ntheta = exp(-ntheta);

	if (include_summand<propto,T_prob>::value) {
	  // Handle extreme values gracefully using Taylor approximations.
	  const static double cutoff = 20.0;
	  if (ntheta > cutoff)
	    logp -= exp_m_ntheta;
	  else if (ntheta < -cutoff)
	    logp += ntheta;
	  else
	    logp -= log1p(exp_m_ntheta);
	}

	// gradients
	if (!is_constant_struct<T_prob>::value) {
	  const static double cutoff = 20.0;
	  if (ntheta > cutoff)
	    operands_and_partials.d_x1[n] -= exp_m_ntheta;
	  else if (ntheta < -cutoff)
	    operands_and_partials.d_x1[n] += sign;
	  else
	    operands_and_partials.d_x1[n] += sign * exp_m_ntheta / (exp_m_ntheta + 1);
	}
      }
      return operands_and_partials.to_var(logp);
    }

    template <bool propto,
	      typename T_n,
              typename T_prob>
    inline
    typename return_type<T_prob>::type
    bernoulli_logit_log(const T_n& n,
                        const T_prob& theta) {
      return bernoulli_logit_log<propto>(n,theta,stan::math::default_policy());
    }

    template <typename T_n,
	      typename T_prob,
              class Policy>
    inline
    typename return_type<T_prob>::type
    bernoulli_logit_log(const T_n& n,
                        const T_prob& theta,
                        const Policy&) {
      return bernoulli_logit_log<false>(n,theta,Policy());
    }

    template <typename T_n,
	      typename T_prob>
    inline
    typename return_type<T_prob>::type
    bernoulli_logit_log(const T_n& n,
                        const T_prob& theta) {
      return bernoulli_logit_log<false>(n,theta,stan::math::default_policy());
    }

      // Bernoulli CDF
      template <bool propto, typename T_n, typename T_prob, class Policy>
      typename return_type<T_prob>::type
      bernoulli_cdf(const T_n& n, const T_prob& theta, const Policy&) {

          static const char* function = "stan::prob::bernoulli_cdf(%1%)";

          using stan::math::check_finite;
          using stan::math::check_bounded;
          using stan::math::check_consistent_sizes;
          using stan::prob::include_summand;

          // Ensure non-zero argument lenghts
          if (!(stan::length(n) && stan::length(theta)))
              return 0.0;

          double P(1.0);

          // Validate arguments
          if (!check_bounded(function, n, 0, 1, "n", &P, Policy()))
              return P;

          if (!check_finite(function, theta, "Probability parameter", &P, Policy()))
              return P;

          if (!check_bounded(function, theta, 0.0, 1.0,
                             "Probability parameter", &P, Policy()))
              return P;

          if (!(check_consistent_sizes(function,
                                       n, theta,
                                       "Random variable","Probability parameter",
                                       &P, Policy())))
              return P;

          // Return if everything is constant and only proportionality is required
          if (!include_summand<propto,T_prob>::value)
              return 0.0;

          // set up template expressions wrapping scalars into vector views
          VectorView<const T_n> n_vec(n);
          VectorView<const T_prob> theta_vec(theta);
          size_t size = max_size(n, theta);

          // Compute vectorized CDF and gradient
          using stan::math::value_of;
          using boost::math::ibetac;
          using boost::math::ibeta_derivative;

          agrad::OperandsAndPartials<T_prob> operands_and_partials(theta);

          for (size_t i = 0; i < size; i++) {

              const double n_dbl = value_of(n_vec[i]);
              const double theta_dbl = value_of(theta_vec[i]);

              const double Pi = ibetac(n_dbl + 1, 1 - n_dbl, theta_dbl);

              P *= Pi;

              if (!is_constant_struct<T_prob>::value)
                  operands_and_partials.d_x1[i] += - ibeta_derivative(n_dbl + 1, 1 - n_dbl, theta_dbl) / Pi;

          }

          for (size_t i = 0; i < size; i++) {

              if (!is_constant_struct<T_prob>::value)
                  operands_and_partials.d_x1[i] *= P;

          }

          return P;

      }

      template <bool propto, typename T_y, typename T_prob>
      inline typename return_type<T_prob>::type
      bernoulli_cdf(const T_y& n, const T_prob& theta) {
          return bernoulli_log<propto>(n, theta, stan::math::default_policy());
      }

      template <typename T_y, typename T_prob, class Policy>
      inline typename return_type<T_prob>::type
      bernoulli_cdf(const T_y& n, const T_prob& theta, const Policy&) {
          return bernoulli_cdf<false>(n, theta, Policy());
      }

      template <typename T_y, typename T_prob>
      inline typename return_type<T_prob>::type
      bernoulli_cdf(const T_y& n, const T_prob& theta) {
          return bernoulli_cdf<false>(n, theta, stan::math::default_policy());
      }

  }
}
#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *   Copyright (C) 2011-2016 by Paul-Louis Ageneau                       *
 *   paul-louis (at) ageneau (dot) org                                   *
 *                                                                       *
 *   This file is part of Teapotnet.                                     *
 *                                                                       *
 *   Teapotnet is free software: you can redistribute it and/or modify   *
 *   it under the terms of the GNU Affero General Public License as      *
 *   published by the Free Software Foundation, either version 3 of      *
 *   the License, or (at your option) any later version.                 *
 *                                                                       *
 *   Teapotnet is distributed in the hope that it will be useful, but    *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of          *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the        *
 *   GNU Affero General Public License for more details.                 *
 *                                                                       *
 *   You should have received a copy of the GNU Affero General Public    *
 *   License along with Teapotnet.                                       *
 *   If not, see <http://www.gnu.org/licenses/>.                         *
 *************************************************************************/

#include "tpn/request.hpp"
#include "tpn/config.hpp"

#include "pla/jsonserializer.hpp"
#include "pla/mime.hpp"

namespace tpn
{

Request::Request(Resource &resource) :
	mListDirectories(true),
	mFinished(false),
	mAutoDeleteTimeout(-1.)
{
	mUrlPrefix = "/request/" + String::random(32);
	Interface::Instance->add(mUrlPrefix, this);
	addResult(resource, true);	// finished
}

Request::Request(const String &path, bool listDirectories) :
	mPath(path),
	mListDirectories(listDirectories),
	mFinished(false),
	mAutoDeleteTimeout(-1.)
{
	mUrlPrefix = "/request/" + String::random(32);
	Interface::Instance->add(mUrlPrefix, this);
	subscribe(path);
}

Request::Request(const String &path, const Identifier &local, const Identifier &remote, bool listDirectories) :
	Subscriber(Network::Link(local, remote)),
	mPath(path),
	mListDirectories(listDirectories),
	mFinished(false),
	mAutoDeleteTimeout(-1.)
{
	mUrlPrefix = "/request/" + String::random(32);
	Interface::Instance->add(mUrlPrefix, this);
	subscribe(path);
}

Request::Request(const String &path, const Network::Link &link, bool listDirectories) :
	Subscriber(link),
	mPath(path),
	mListDirectories(listDirectories),
	mFinished(false),
	mAutoDeleteTimeout(-1.)
{
	mUrlPrefix = "/request/" + String::random(32);
	Interface::Instance->add(mUrlPrefix, this);
	subscribe(path);
}

Request::~Request(void)
{
	std::unique_lock<std::mutex> lock(mMutex);
	mAutoDeleter.cancel();
	Interface::Instance->remove(mUrlPrefix, this);
	unsubscribeAll();
}

bool Request::addTarget(const BinaryString &target)
{
	if(mPath.empty() || target.empty()) return false;
	return incoming(link(), mPath, "/", target);
}

String Request::urlPrefix(void) const
{
	std::unique_lock<std::mutex> lock(mMutex);
	return mUrlPrefix;
}

int Request::resultsCount(void) const
{
	std::unique_lock<std::mutex> lock(mMutex);
	return int(mResults.size());
}

void Request::addResult(Resource &resource, bool finish)
{
	if(resource.isDirectory() && mListDirectories)
	{
		// List directory and add records
		Resource::Reader reader(&resource);
		Resource::DirectoryRecord record;
		while(reader.readDirectory(record))
			addResult(record);
	}
	else {
		// Do not list, just add corresponding record
		addResult(resource.getDirectoryRecord());
	}

	if(finish)
	{
		std::unique_lock<std::mutex> lock(mMutex);
		mFinished = true;
	}
}

void Request::addResult(const Resource::DirectoryRecord &record)
{
	std::unique_lock<std::mutex> lock(mMutex);

	if(!mDigests.contains(record.digest))
	{
		//LogDebug("Request", "Adding result: " + record.digest.toString() + " (" + record.name + ")");

		mResults.append(record);
		mDigests.insert(record.digest);
		lock.unlock();
		mCondition.notify_all();
	}
}

void Request::getResult(int i, Resource::DirectoryRecord &record) const
{
	std::unique_lock<std::mutex> lock(mMutex);
	Assert(i < resultsCount());
	record = mResults.at(i);
}

void Request::autoDelete(duration timeout)
{
	std::unique_lock<std::mutex> lock(mMutex);
	if(timeout >= duration::zero()) mAutoDeleter.schedule(timeout, [this]() { delete this; });
	else mAutoDeleter.cancel();
	mAutoDeleteTimeout = timeout;
}

void Request::http(const String &prefix, Http::Request &request)
{
	std::unique_lock<std::mutex> lock(mMutex);	// Request::http() is synced !

	int next = 0;
	if(request.get.contains("next"))
		request.get["next"].extract(next);

	duration timeout = milliseconds(Config::Get("request_timeout").toDouble());
	if(request.get.contains("timeout"))
		timeout = milliseconds(request.get["timeout"].toDouble());

	if(int(mResults.size()) <= next && !mFinished)
	{
		mAutoDeleter.cancel();

		if(mCondition.wait_for(lock, timeout, [this, next]() {
			return int(mResults.size()) > next || mFinished;
		}));
	}

	if(mAutoDeleteTimeout >= duration::zero())
		mAutoDeleter.schedule(timeout);

	// Playlist
	if(request.get.contains("playlist"))
	{
		int start = -1;
		int stop  = -1;

		String startParam;
		if(request.get.get("start", startParam) || request.get.get("t", startParam))
			start = timeParamToSeconds(startParam);

		String stopParam;
                if(request.get.get("stop", stopParam))
                        stop = timeParamToSeconds(stopParam);

		Http::Response response(request, 200);
		response.headers["Content-Disposition"] = "attachment; filename=\"playlist.m3u\"";
		response.headers["Content-Type"] = "audio/x-mpegurl";
		response.send();

		String host;
		request.headers.get("Host", host);
		createPlaylist(response.stream, host, start, stop);
	}
	else {
		// JSON

		Http::Response response(request, 200);
		response.headers["Content-Type"] = "application/json";
		response.send();

		std::list<Resource::DirectoryRecord*> tmp;
		if(int(mResults.size()) > next)
			for(int i = next; i < int(mResults.size()); ++i)
				tmp.push_back(&mResults[i]);

		JsonSerializer(response.stream) << tmp;
	}
}

bool Request::incoming(const Network::Link &link, const String &prefix, const String &path, const BinaryString &target)
{
	if(fetch(link, prefix, path, target, false))	// no content
	{
		Resource resource(target, true);	// local only
		if(!mListDirectories || !resource.isDirectory() || fetch(link, prefix, path, target, true))
			addResult(resource);
	}

	return true;
}

void Request::createPlaylist(Stream *output, String host, int start, int stop)
{
	std::unique_lock<std::mutex> lock(mMutex);
	Assert(output);

	if(host.empty())
		host = String("localhost:") + Config::Get("interface_port");

	output->writeLine("#EXTM3U");
	for(int i = 0; i < int(mResults.size()); ++i)
	{
		const Resource::DirectoryRecord &record = mResults[i];
		if(record.type == "directory" || record.digest.empty()) continue;
		if(!Mime::IsAudio(record.name) && !Mime::IsVideo(record.name)) continue;
		String link = "http://" + host + "/file/" + record.digest.toString();
		output->writeLine("#EXTINF:-1," + record.name.beforeLast('.'));
		if(start >= 0) output->writeLine("#EXTVLCOPT:start-time=" + String::number(start));
		if(stop >= 0)  output->writeLine("#EXTVLCOPT:stop-time="  + String::number(stop));
		output->writeLine(link);
		start = stop = -1;
	}
}

int Request::timeParamToSeconds(String param)
{
	try {
		int s = 0;

		if(param.contains("h"))
		{
			String hours = param;
			param = hours.cut('h');
			s+= hours.toInt()*3600;

			if(!param.contains("m") && !param.contains("s"))
				param+= 'm';
		}

		if(param.contains("m"))
		{
			String minutes = param;
			param = minutes.cut('m');
			s+= minutes.toInt()*60;
		}

		param.cut('s');
		s+= param.toInt();
		return s;
	}
	catch(const std::exception &e)
	{
		return -1;
	}
}

}

<commit_msg>Fixed deadlock with Request::createPlaylist()<commit_after>/*************************************************************************
 *   Copyright (C) 2011-2016 by Paul-Louis Ageneau                       *
 *   paul-louis (at) ageneau (dot) org                                   *
 *                                                                       *
 *   This file is part of Teapotnet.                                     *
 *                                                                       *
 *   Teapotnet is free software: you can redistribute it and/or modify   *
 *   it under the terms of the GNU Affero General Public License as      *
 *   published by the Free Software Foundation, either version 3 of      *
 *   the License, or (at your option) any later version.                 *
 *                                                                       *
 *   Teapotnet is distributed in the hope that it will be useful, but    *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of          *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the        *
 *   GNU Affero General Public License for more details.                 *
 *                                                                       *
 *   You should have received a copy of the GNU Affero General Public    *
 *   License along with Teapotnet.                                       *
 *   If not, see <http://www.gnu.org/licenses/>.                         *
 *************************************************************************/

#include "tpn/request.hpp"
#include "tpn/config.hpp"

#include "pla/jsonserializer.hpp"
#include "pla/mime.hpp"

namespace tpn
{

Request::Request(Resource &resource) :
	mListDirectories(true),
	mFinished(false),
	mAutoDeleteTimeout(-1.)
{
	mUrlPrefix = "/request/" + String::random(32);
	Interface::Instance->add(mUrlPrefix, this);
	addResult(resource, true);	// finished
}

Request::Request(const String &path, bool listDirectories) :
	mPath(path),
	mListDirectories(listDirectories),
	mFinished(false),
	mAutoDeleteTimeout(-1.)
{
	mUrlPrefix = "/request/" + String::random(32);
	Interface::Instance->add(mUrlPrefix, this);
	subscribe(path);
}

Request::Request(const String &path, const Identifier &local, const Identifier &remote, bool listDirectories) :
	Subscriber(Network::Link(local, remote)),
	mPath(path),
	mListDirectories(listDirectories),
	mFinished(false),
	mAutoDeleteTimeout(-1.)
{
	mUrlPrefix = "/request/" + String::random(32);
	Interface::Instance->add(mUrlPrefix, this);
	subscribe(path);
}

Request::Request(const String &path, const Network::Link &link, bool listDirectories) :
	Subscriber(link),
	mPath(path),
	mListDirectories(listDirectories),
	mFinished(false),
	mAutoDeleteTimeout(-1.)
{
	mUrlPrefix = "/request/" + String::random(32);
	Interface::Instance->add(mUrlPrefix, this);
	subscribe(path);
}

Request::~Request(void)
{
	std::unique_lock<std::mutex> lock(mMutex);
	mAutoDeleter.cancel();
	Interface::Instance->remove(mUrlPrefix, this);
	unsubscribeAll();
}

bool Request::addTarget(const BinaryString &target)
{
	if(mPath.empty() || target.empty()) return false;
	return incoming(link(), mPath, "/", target);
}

String Request::urlPrefix(void) const
{
	std::unique_lock<std::mutex> lock(mMutex);
	return mUrlPrefix;
}

int Request::resultsCount(void) const
{
	std::unique_lock<std::mutex> lock(mMutex);
	return int(mResults.size());
}

void Request::addResult(Resource &resource, bool finish)
{
	if(resource.isDirectory() && mListDirectories)
	{
		// List directory and add records
		Resource::Reader reader(&resource);
		Resource::DirectoryRecord record;
		while(reader.readDirectory(record))
			addResult(record);
	}
	else {
		// Do not list, just add corresponding record
		addResult(resource.getDirectoryRecord());
	}

	if(finish)
	{
		std::unique_lock<std::mutex> lock(mMutex);
		mFinished = true;
	}
}

void Request::addResult(const Resource::DirectoryRecord &record)
{
	std::unique_lock<std::mutex> lock(mMutex);

	if(!mDigests.contains(record.digest))
	{
		//LogDebug("Request", "Adding result: " + record.digest.toString() + " (" + record.name + ")");

		mResults.append(record);
		mDigests.insert(record.digest);
		lock.unlock();
		mCondition.notify_all();
	}
}

void Request::getResult(int i, Resource::DirectoryRecord &record) const
{
	std::unique_lock<std::mutex> lock(mMutex);
	Assert(i < resultsCount());
	record = mResults.at(i);
}

void Request::autoDelete(duration timeout)
{
	std::unique_lock<std::mutex> lock(mMutex);
	if(timeout >= duration::zero()) mAutoDeleter.schedule(timeout, [this]() { delete this; });
	else mAutoDeleter.cancel();
	mAutoDeleteTimeout = timeout;
}

void Request::http(const String &prefix, Http::Request &request)
{
	std::unique_lock<std::mutex> lock(mMutex);	// Request::http() is synced !

	int next = 0;
	if(request.get.contains("next"))
		request.get["next"].extract(next);

	duration timeout = milliseconds(Config::Get("request_timeout").toDouble());
	if(request.get.contains("timeout"))
		timeout = milliseconds(request.get["timeout"].toDouble());

	if(int(mResults.size()) <= next && !mFinished)
	{
		mAutoDeleter.cancel();

		if(mCondition.wait_for(lock, timeout, [this, next]() {
			return int(mResults.size()) > next || mFinished;
		}));
	}

	if(mAutoDeleteTimeout >= duration::zero())
		mAutoDeleter.schedule(timeout);

	// Playlist
	if(request.get.contains("playlist"))
	{
		int start = -1;
		int stop  = -1;

		String startParam;
		if(request.get.get("start", startParam) || request.get.get("t", startParam))
			start = timeParamToSeconds(startParam);

		String stopParam;
                if(request.get.get("stop", stopParam))
                        stop = timeParamToSeconds(stopParam);

		Http::Response response(request, 200);
		response.headers["Content-Disposition"] = "attachment; filename=\"playlist.m3u\"";
		response.headers["Content-Type"] = "audio/x-mpegurl";
		response.send();

		String host;
		request.headers.get("Host", host);
		createPlaylist(response.stream, host, start, stop);
	}
	else {
		// JSON

		Http::Response response(request, 200);
		response.headers["Content-Type"] = "application/json";
		response.send();

		std::list<Resource::DirectoryRecord*> tmp;
		if(int(mResults.size()) > next)
			for(int i = next; i < int(mResults.size()); ++i)
				tmp.push_back(&mResults[i]);

		JsonSerializer(response.stream) << tmp;
	}
}

bool Request::incoming(const Network::Link &link, const String &prefix, const String &path, const BinaryString &target)
{
	if(fetch(link, prefix, path, target, false))	// no content
	{
		Resource resource(target, true);	// local only
		if(!mListDirectories || !resource.isDirectory() || fetch(link, prefix, path, target, true))
			addResult(resource);
	}

	return true;
}

void Request::createPlaylist(Stream *output, String host, int start, int stop)
{
	Assert(output);

	if(host.empty())
		host = String("localhost:") + Config::Get("interface_port");

	output->writeLine("#EXTM3U");
	for(int i = 0; i < int(mResults.size()); ++i)
	{
		const Resource::DirectoryRecord &record = mResults[i];
		if(record.type == "directory" || record.digest.empty()) continue;
		if(!Mime::IsAudio(record.name) && !Mime::IsVideo(record.name)) continue;
		String link = "http://" + host + "/file/" + record.digest.toString();
		output->writeLine("#EXTINF:-1," + record.name.beforeLast('.'));
		if(start >= 0) output->writeLine("#EXTVLCOPT:start-time=" + String::number(start));
		if(stop >= 0)  output->writeLine("#EXTVLCOPT:stop-time="  + String::number(stop));
		output->writeLine(link);
		start = stop = -1;
	}
}

int Request::timeParamToSeconds(String param)
{
	try {
		int s = 0;

		if(param.contains("h"))
		{
			String hours = param;
			param = hours.cut('h');
			s+= hours.toInt()*3600;

			if(!param.contains("m") && !param.contains("s"))
				param+= 'm';
		}

		if(param.contains("m"))
		{
			String minutes = param;
			param = minutes.cut('m');
			s+= minutes.toInt()*60;
		}

		param.cut('s');
		s+= param.toInt();
		return s;
	}
	catch(const std::exception &e)
	{
		return -1;
	}
}

}

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkGeoSampleArcs.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/
#include "vtkGeoSampleArcs.h"

#include "vtkCamera.h"
#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkCoordinate.h"
#include "vtkDoubleArray.h"
#include "vtkFloatArray.h"
#include "vtkGeoMath.h"
#include "vtkGlobeSource.h"
#include "vtkMath.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkRenderWindow.h"
#include "vtkRendererCollection.h"
#include "vtkTimerLog.h"

#include <vtksys/stl/map>
using vtksys_stl::map;

vtkCxxRevisionMacro(vtkGeoSampleArcs, "1.1");
vtkStandardNewMacro(vtkGeoSampleArcs);

vtkGeoSampleArcs::vtkGeoSampleArcs()
{
  this->GlobeRadius = vtkGeoMath::EarthRadiusMeters();
  this->MaximumDistanceMeters = 100000.0;
}

vtkGeoSampleArcs::~vtkGeoSampleArcs()
{
}

int vtkGeoSampleArcs::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // get the input and ouptut
  vtkPolyData *input = vtkPolyData::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkPolyData *output = vtkPolyData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  // Traverse input lines, adding a circle for each line segment.
  vtkCellArray* lines = input->GetLines();
  vtkCellArray* newLines = vtkCellArray::New();
  vtkPoints* points = input->GetPoints();
  float* pointsPtr = static_cast<float*>(points->GetVoidPointer(0));
  vtkPoints* newPoints = vtkPoints::New();
  lines->InitTraversal();
  for (vtkIdType i = 0; i < lines->GetNumberOfCells(); i++)
    {
    vtkIdType npts;
    vtkIdType* pts;
    lines->GetNextCell(npts, pts);

    double lastPoint[3];
    double curPoint[3];
    double lastPtLL[2];
    double curPtLL[2];
    double lastVec[3];
    double curVec[3];
    curPoint[0] = pointsPtr[3*pts[0]+0];
    curPoint[1] = pointsPtr[3*pts[0]+1];
    curPoint[2] = pointsPtr[3*pts[0]+2];
    vtkGlobeSource::ComputeLatitudeLongitude(
      curPoint, curPtLL[0], curPtLL[1]);

    for (vtkIdType p = 1; p < npts; ++p)
      {
      // Advance point
      for (int c = 0; c < 3; ++c)
        {
        lastPoint[c] = curPoint[c];
        }
      lastPtLL[0] = curPtLL[0];
      lastPtLL[1] = curPtLL[1];
      curPoint[0] = pointsPtr[3*pts[p]+0];
      curPoint[1] = pointsPtr[3*pts[p]+1];
      curPoint[2] = pointsPtr[3*pts[p]+2];
      vtkGlobeSource::ComputeLatitudeLongitude(
        curPoint, curPtLL[0], curPtLL[1]);

      double dist = sqrt(vtkMath::Distance2BetweenPoints(lastPoint, curPoint));

      // Calculate the number of subdivisions.
      vtkIdType numDivisions = static_cast<vtkIdType>(dist / this->MaximumDistanceMeters + 0.5) + 1;
      if (numDivisions < 2)
        {
        numDivisions = 2;
        }

      // Create the new cell
      newLines->InsertNextCell(numDivisions);

      for (vtkIdType s = 0; s < numDivisions; ++s)
        {
        // Interpolate in lat-long.
        double interpPtLL[2];
        double frac = static_cast<double>(s) / (numDivisions - 1);
        for (int c = 0; c < 2; ++c)
          {
          interpPtLL[c] = frac*curPtLL[c] + (1.0 - frac)*lastPtLL[c];
          }
        // Convert lat-long to world;
        double interpPt[3];
        vtkGlobeSource::ComputeGlobePoint(interpPtLL[0], interpPtLL[1], this->GlobeRadius, interpPt);
        vtkIdType newPt = newPoints->InsertNextPoint(interpPt);
        newLines->InsertCellPoint(newPt);
        }

      }
    }

  // Send the data to output.
  output->SetLines(newLines);
  output->SetPoints(newPoints);

  // Clean up.
  newLines->Delete();
  newPoints->Delete();

  return 1;
}

void vtkGeoSampleArcs::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "GlobeRadius: " << this->GlobeRadius << endl;
  os << indent << "MaximumDistanceMeters: " << this->MaximumDistanceMeters << endl;
}

<commit_msg>COMP: fix warning<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkGeoSampleArcs.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/
#include "vtkGeoSampleArcs.h"

#include "vtkCamera.h"
#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkCoordinate.h"
#include "vtkDoubleArray.h"
#include "vtkFloatArray.h"
#include "vtkGeoMath.h"
#include "vtkGlobeSource.h"
#include "vtkMath.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkRenderWindow.h"
#include "vtkRendererCollection.h"
#include "vtkTimerLog.h"

#include <vtksys/stl/map>
using vtksys_stl::map;

vtkCxxRevisionMacro(vtkGeoSampleArcs, "1.2");
vtkStandardNewMacro(vtkGeoSampleArcs);

vtkGeoSampleArcs::vtkGeoSampleArcs()
{
  this->GlobeRadius = vtkGeoMath::EarthRadiusMeters();
  this->MaximumDistanceMeters = 100000.0;
}

vtkGeoSampleArcs::~vtkGeoSampleArcs()
{
}

int vtkGeoSampleArcs::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // get the input and ouptut
  vtkPolyData *input = vtkPolyData::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkPolyData *output = vtkPolyData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  // Traverse input lines, adding a circle for each line segment.
  vtkCellArray* lines = input->GetLines();
  vtkCellArray* newLines = vtkCellArray::New();
  vtkPoints* points = input->GetPoints();
  float* pointsPtr = static_cast<float*>(points->GetVoidPointer(0));
  vtkPoints* newPoints = vtkPoints::New();
  lines->InitTraversal();
  for (vtkIdType i = 0; i < lines->GetNumberOfCells(); i++)
    {
    vtkIdType npts;
    vtkIdType* pts;
    lines->GetNextCell(npts, pts);

    double lastPoint[3];
    double curPoint[3];
    double lastPtLL[2];
    double curPtLL[2];
    curPoint[0] = pointsPtr[3*pts[0]+0];
    curPoint[1] = pointsPtr[3*pts[0]+1];
    curPoint[2] = pointsPtr[3*pts[0]+2];
    vtkGlobeSource::ComputeLatitudeLongitude(
      curPoint, curPtLL[0], curPtLL[1]);

    for (vtkIdType p = 1; p < npts; ++p)
      {
      // Advance point
      for (int c = 0; c < 3; ++c)
        {
        lastPoint[c] = curPoint[c];
        }
      lastPtLL[0] = curPtLL[0];
      lastPtLL[1] = curPtLL[1];
      curPoint[0] = pointsPtr[3*pts[p]+0];
      curPoint[1] = pointsPtr[3*pts[p]+1];
      curPoint[2] = pointsPtr[3*pts[p]+2];
      vtkGlobeSource::ComputeLatitudeLongitude(
        curPoint, curPtLL[0], curPtLL[1]);

      double dist = sqrt(vtkMath::Distance2BetweenPoints(lastPoint, curPoint));

      // Calculate the number of subdivisions.
      vtkIdType numDivisions = static_cast<vtkIdType>(dist / this->MaximumDistanceMeters + 0.5) + 1;
      if (numDivisions < 2)
        {
        numDivisions = 2;
        }

      // Create the new cell
      newLines->InsertNextCell(numDivisions);

      for (vtkIdType s = 0; s < numDivisions; ++s)
        {
        // Interpolate in lat-long.
        double interpPtLL[2];
        double frac = static_cast<double>(s) / (numDivisions - 1);
        for (int c = 0; c < 2; ++c)
          {
          interpPtLL[c] = frac*curPtLL[c] + (1.0 - frac)*lastPtLL[c];
          }
        // Convert lat-long to world;
        double interpPt[3];
        vtkGlobeSource::ComputeGlobePoint(interpPtLL[0], interpPtLL[1], this->GlobeRadius, interpPt);
        vtkIdType newPt = newPoints->InsertNextPoint(interpPt);
        newLines->InsertCellPoint(newPt);
        }

      }
    }

  // Send the data to output.
  output->SetLines(newLines);
  output->SetPoints(newPoints);

  // Clean up.
  newLines->Delete();
  newPoints->Delete();

  return 1;
}

void vtkGeoSampleArcs::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "GlobeRadius: " << this->GlobeRadius << endl;
  os << indent << "MaximumDistanceMeters: " << this->MaximumDistanceMeters << endl;
}

<|endoftext|>