/**
   * Performs a transposed mass evaluation
   *
   * @param storage GridStorage object that contains the grid's points information
   * @param basis a reference to a class that implements a specific basis
   * @param source the coefficients of the grid points
   * @param x the d-dimensional vector with data points (row-wise)
   * @param result the result vector of the matrix vector multiplication
   */
  void mult_transpose(GridStorage* storage, BASIS& basis, DataVector& source,
                      DataMatrix& x, DataVector& result) {
    result.setAll(0.0);
    size_t source_size = source.getSize();

    #pragma omp parallel
    {
      DataVector privateResult(result.getSize());
      privateResult.setAll(0.0);

      DataVector line(x.getNcols());
      AlgorithmEvaluationTransposed<BASIS> AlgoEvalTrans(storage);

      privateResult.setAll(0.0);


      #pragma omp for schedule(static)

      for (size_t i = 0; i < source_size; i++) {
        x.getRow(i, line);

        AlgoEvalTrans(basis, line, source[i], privateResult);
      }

      #pragma omp critical
      {
        result.add(privateResult);
      }
    }
  }
void SolveEvolutionMatrix(
	DataMatrix<double> & matM,
	DataMatrix<double> & matB,
	DataVector<double> & vecAlphaR,
	DataVector<double> & vecAlphaI,
	DataVector<double> & vecBeta,
	DataMatrix<double> & matVR
) {
	int iInfo = 0;

	char jobvl = 'N';
	char jobvr = 'V';

	int n = matM.GetRows();
	int lda = matM.GetRows();
	int ldb = matM.GetRows();
	int ldvl = 1;
	int ldvr = matVR.GetRows();

	DataVector<double> vecWork;
	vecWork.Initialize(8 * n);
	int lwork = vecWork.GetRows();

	dggev_(
		&jobvl,
		&jobvr,
		&n,
		&(matM[0][0]),
		&lda,
		&(matB[0][0]),
		&ldb,
		&(vecAlphaR[0]),
		&(vecAlphaI[0]),
		&(vecBeta[0]),
		NULL,
		&ldvl,
		&(matVR[0][0]),
		&ldvr,
		&(vecWork[0]),
		&lwork,
		&iInfo);

	int nCount = 0;
	for (int i = 0; i < n; i++) {
		if (vecBeta[i] != 0.0) {
			//printf("%i %1.5e %1.5e\n", i, vecAlphaR[i] / vecBeta[i], vecAlphaI[i] / vecBeta[i]);
			nCount++;
		}
	}
/*
	for (int i = 0; i < 40; i++) {
		printf("%1.5e %1.5e\n", matVR[11][4*i+2], matVR[12][4*i+2]);
	}
*/
	Announce("%i total eigenvalues found", nCount);
}
Пример #3
0
int main(int, char**)
{
    cout.precision(3);
    typedef Matrix<float,Dynamic,2> DataMatrix;
// let's generate some samples on the 3D plane of equation z = 2x+3y (with some noise)
    DataMatrix samples = DataMatrix::Random(12,2);
    VectorXf elevations = 2*samples.col(0) + 3*samples.col(1) + VectorXf::Random(12)*0.1;
// and let's solve samples * [x y]^T = elevations in least square sense:
    Matrix<float,2,1> xy
        = (samples.adjoint() * samples).llt().solve((samples.adjoint()*elevations));
    cout << xy << endl;

    return 0;
}
Пример #4
0
 /*! \brief save a DataMatrix as DMatrixPage */
 inline static void Save(const char *fname_, const DataMatrix &mat, bool silent) {
   std::string fname = fname_;
   utils::FileStream fs(utils::FopenCheck(fname.c_str(), "wb"));
   int magic = kMagic;
   fs.Write(&magic, sizeof(magic));
   mat.info.SaveBinary(fs);
   fs.Close();
   fname += ".row.blob";
   utils::IIterator<RowBatch> *iter = mat.fmat()->RowIterator();
   utils::FileStream fbin(utils::FopenCheck(fname.c_str(), "wb"));
   SparsePage page;
   iter->BeforeFirst();
   while (iter->Next()) {
     const RowBatch &batch = iter->Value();
     for (size_t i = 0; i < batch.size; ++i) {
       page.Push(batch[i]);
       if (page.MemCostBytes() >= kPageSize) {
         page.Save(&fbin); page.Clear();
       }
     }
   }
   if (page.data.size() != 0) page.Save(&fbin);
   fbin.Close();
   if (!silent) {
     utils::Printf("DMatrixPage: %lux%lu is saved to %s\n",
                   static_cast<unsigned long>(mat.info.num_row()),
                   static_cast<unsigned long>(mat.info.num_col()), fname_);
   }
 }
Пример #5
0
 inline void BoostOneIter(const DataMatrix &train,
                          float *grad, float *hess, bst_ulong len) {
   this->gpair_.resize(len);
   const bst_omp_uint ndata = static_cast<bst_omp_uint>(len);
   #pragma omp parallel for schedule(static)
   for (bst_omp_uint j = 0; j < ndata; ++j) {
     gpair_[j] = bst_gpair(grad[j], hess[j]);
   }
   gbm_->DoBoost(train.fmat(), train.info.info, &gpair_);
 }
  /**
   * Performs a mass evaluation
   *
   * @param storage GridStorage object that contains the grid's points information
   * @param basis a reference to a class that implements a specific basis
   * @param source the coefficients of the grid points
   * @param x the d-dimensional vector with data points (row-wise)
   * @param result the result vector of the matrix vector multiplication
   */
  void mult(GridStorage* storage, BASIS& basis, DataVector& source, DataMatrix& x,
            DataVector& result) {
    result.setAll(0.0);
    size_t result_size = result.getSize();


    #pragma omp parallel
    {
      DataVector line(x.getNcols());
      AlgorithmEvaluation<BASIS> AlgoEval(storage);

      #pragma omp for schedule(static)

      for (size_t i = 0; i < result_size; i++) {
        x.getRow(i, line);

        result[i] = AlgoEval(basis, line, source);
      }
    }
  }
Пример #7
0
typedef Matrix<float,Dynamic,2> DataMatrix;
// let's generate some samples on the 3D plane of equation z = 2x+3y (with some noise)
DataMatrix samples = DataMatrix::Random(12,2);
VectorXf elevations = 2*samples.col(0) + 3*samples.col(1) + VectorXf::Random(12)*0.1;
// and let's solve samples * [x y]^T = elevations in least square sense:
Matrix<float,2,1> xy
 = (samples.adjoint() * samples).llt().solve((samples.adjoint()*elevations));
cout << xy << endl;
Пример #8
0
void ActiveConnect(ArgListType &arg) //AT_FUN
{
   // process the function arguments
   static string FunctionName = "ActiveConnect";
   static IntArg StartNeuron("-Nstart", "start neuron", 1);
   static IntArg EndNeuron("-Nend", "end neuron{-1 gives last neuron}", -1);
   static IntArg StartPat("-Pstart", "start pattern(or vector)", 1);
   static IntArg EndPat("-Pend", "end pattern(or vector) {-1 gives end time}",
                        -1);
   static StrArg SeqName("-name", "sequence name");
   static StrArg ResetSeq("-reset", "reset sequence", "{zeros}");
   static StrArg External("-ext", "external sequence", "{zeros}");
   static FlagArg DoSummary("-sum", "-nosum", "print a summary", 1);
   static int argunset = true;
   static CommandLine ComL(FunctionName);
   if (argunset) {
      ComL.HelpSet("@ActiveConnect() \n"
                   "\tGenerates the data about conditional probabilities of firing\n"
                   "\tand saves the results into the ActiveConBuffer.\n"
                   "\tThe reset sequence is used for the 0 time step and\n"
                   "\tif externals are given then they are ignored.\n"
                   "\tActiveConBuffer is a matrix with 6 Vectors:\n"
                   "\t\t1: TimeStep(Pattern Number)\n"
                   "\t\t2: Absolute Activity Last Time\n"
                   "\t\t3: Absolute Activity This Time - Externals\n"
                   "\t\t4: # of Conns between CoActive Neurons\n"
                   "\t\t5: 4/3 = Ave # of Active Conns for Active Neurons\n"
                   "\t\t6: 4/(2*3) = Prob cij=1 given zi=1,zj=1\n"
                   "\tActiveConnect also updates the variable Pczz which\n"
                   "\tholds the Prob(cij=1 | zi=1,zj=1) for the whole sequence\n");
      ComL.IntSet(4, &StartNeuron, &EndNeuron, &StartPat, &EndPat);
      ComL.StrSet(3, &SeqName, &ResetSeq, &External);
      ComL.FlagSet(1, &DoSummary);
      argunset = false;
   }
   ComL.Process(arg, Output::Err());

   if (!program::Main().getNetworkCreated()) {
      CALL_ERROR << "Error: You must call @CreateNetwork() before you can "
                    "call @ActiveConnect." << ERR_WHERE;
      exit(EXIT_FAILURE);
   }
   UIPtnSequence Seq = SystemVar::getSequence(SeqName, FunctionName, ComL);
   int SeqSize = Seq.size();
   UIPtnSequence ReSeq;
   if (ResetSeq.getValue() != "{zeros}") {
      ReSeq = SystemVar::getSequence(ResetSeq, FunctionName, ComL);
   } else {
      ReSeq.resize(SeqSize, UIVector(0));
   }
   int lastNeuron = 0;
   for (UIPtnSequenceCIt it = Seq.begin(); it != Seq.end(); it++) {
      updateMax(lastNeuron, it->back());
   }
   if (EndNeuron.getValue() == -1) {
      EndNeuron.setValue(lastNeuron);
   }
   if (EndPat.getValue() == -1) {
      EndPat.setValue(SeqSize);
   }
   if (StartNeuron.getValue() < 1 ||
         StartNeuron.getValue() > EndNeuron.getValue() ||
         EndNeuron.getValue() > static_cast<int>(ni)) {
      CALL_ERROR << "Error in " << FunctionName << ": Neuron range of "
          << StartNeuron.getValue() << "..." << EndNeuron.getValue()
          << " is invalid." << ERR_WHERE;
      ComL.DisplayHelp(Output::Err());
   }
   if (EndPat.getValue() < 1 || EndPat.getValue() > SeqSize ||
          StartPat.getValue() < 1 || StartPat.getValue() > EndPat.getValue()) {
      CALL_ERROR << "Error in " << FunctionName << ": Pattern range of "
         << StartPat.getValue() << "..." << EndPat.getValue() << " is invalid."
         << ERR_WHERE;
      ComL.DisplayHelp(Output::Err());
   }

   // get externals
   UIMatrix ExtSeq;
   if (External.getValue() != "{zeros}") {
      ExtSeq = SystemVar::getSequence(External, FunctionName, ComL);
   } else {
      ExtSeq.resize(SeqSize, UIVector(0));
   }

   // Do the loops
   int NumPats = EndPat.getValue() - StartPat.getValue() + 1;
   DataList Ave(NumPats);
   DataList Sum(NumPats);
   DataList Pats(NumPats);
   DataList jNumFired(NumPats);
   DataList iNumFired(NumPats);
   DataList PczzV(NumPats);
   int index = 0;
   UIPtnSequenceCIt SeqConstIterator = Seq.begin();
   UIPtnSequenceCIt ExtConstIterator = ExtSeq.begin();   
   UIVector pat_b4;
   if (StartPat.getValue() == 1) {
      pat_b4 = ReSeq.front();
   } else {
      for (int inc = 0; inc < StartPat.getValue() - 2; ++inc) ++SeqConstIterator;
      pat_b4 = *(SeqConstIterator++);
   }
   for (int t = StartPat.getValue(); t <= EndPat.getValue(); ++t, ++index, ++SeqConstIterator, ++ExtConstIterator) {
      Pats.at(index) = static_cast<float>(t);
      Pattern pat = UIVectorToPtn(*SeqConstIterator, lastNeuron);
      Pattern pat_ext = UIVectorToPtn(*ExtConstIterator, lastNeuron);
      for (int j = StartNeuron.getValue(); j <= EndNeuron.getValue(); j++) {
         // count the number on
         if (pat_b4.at(j-1)) ++iNumFired.at(index);
         // do the calculation for non-externals and active
         if (pat.at(j-1) && (!(pat_ext.at(j-1)))) {
            ++jNumFired.at(index);
            for (unsigned int c = 0; c < FanInCon.at(j-1); c++) {
               if (pat_b4.at(inMatrix[j-1][c].getSrcNeuron()))
                  ++Sum.at(index);
            }
         }
      }
      pat_b4 = pat;
   }

   // Output the data
   Output::Out() << "\nSummed Active Connections in sequence " << SeqName.getValue()
                 << " using neurons " << StartNeuron.getValue() << "..."
                 << EndNeuron.getValue() << " and patterns " << StartPat.getValue()
                 << "..." << EndPat.getValue() << "\n\tignoring externals given by "
                 << External.getValue();

   if (DoSummary.getValue()) {
      Output::Out() << "\n" << std::setw(11) << "1:TimeStep"
                    << std::setw(9) << "2:#z(t-1)"
                    << std::setw(9) << "3:#z(t)"
                    << std::setw(15) << "4:#cz(t-1)z(t)"
                    << std::setw(9) << "4/3" << std::setw(9) << "4/(2*3)" << "\n";
   }

   float TotalSumC = 0.0f;
   float TotalSumZ = 0.0f;

   for (int i = 0; i < index; i++) {
      if (fabs(Sum.at(i)) < verySmallFloat) {
         Ave.at(i) = 0.0f;
         PczzV.at(i) = 0.0f;
      } else {
         Ave.at(i) = Sum.at(i) / jNumFired.at(i);
         PczzV.at(i) = Ave.at(i) / iNumFired.at(i);
      }
      TotalSumC += Sum.at(i);
      TotalSumZ += iNumFired.at(i) * jNumFired.at(i);
      if (DoSummary.getValue()) {
         Output::Out() << "\n" << std::setw(11) << static_cast<int>(Pats.at(i))
                       << std::setw(9) << static_cast<int>(iNumFired.at(i))
                       << std::setw(9) << static_cast<int>(jNumFired.at(i))
                       << std::setw(15) << static_cast<int>(Sum.at(i))
                       << std::setw(9) << Ave.at(i)
                       << std::setw(9) << PczzV.at(i);
      }
   }
   Output::Out() << "\n";

   float Pczz;
   if (fabs(TotalSumC) < verySmallFloat) {
      Pczz = 0.0f;
   } else {
      Pczz = TotalSumC / TotalSumZ;
   }
   SystemVar::SetFloatVar("Pczz", Pczz);

   if (DoSummary.getValue()) {
      Output::Out() << "Average: " << Pczz << "\n";
   }
   // Save the vector to the ActiveConBuffer
   DataMatrix ActiveConMat;
   ActiveConMat.push_back(Pats);
   ActiveConMat.push_back(iNumFired);
   ActiveConMat.push_back(jNumFired);
   ActiveConMat.push_back(Sum);
   ActiveConMat.push_back(Ave);
   ActiveConMat.push_back(PczzV);
   SystemVar::insertData("ActiveConBuffer", ActiveConMat, DLT_matrix);

   return;
}
int main(int argc, char ** argv) {

	MPI_Init(&argc, &argv);

try {

	// Number of latitudes
	int nLat;

	// Number of longitudes
	int nLon;

	// Zonal wavenumber
	int nK;

	// Meridional power
	int nLpow;

	// Output file
	std::string strOutputFile;

	// Parse the command line
	BeginCommandLine()
		CommandLineInt(nLat, "lat", 40);
		CommandLineInt(nLon, "lon", 80);
		CommandLineString(strOutputFile, "out", "topo.nc");

		ParseCommandLine(argc, argv);
	EndCommandLine(argv)

	// Generate longitude and latitude arrays
	AnnounceBanner();
	AnnounceStartBlock("Generating longitude and latitude arrays");

	DataVector<double> dLon;
	dLon.Initialize(nLon);

	Parameters param;
	param.GenerateLatituteArray(nLat);

	std::vector<double> & dLat = param.vecNode;

	double dDeltaLon = 2.0 * M_PI / static_cast<double>(nLon);
	for (int i = 0; i < nLon; i++) {
		dLon[i] = (static_cast<double>(i) + 0.5) * dDeltaLon;
	}

	AnnounceEndBlock("Done");

	// Open NetCDF output file
	AnnounceStartBlock("Writing to file");

	NcFile ncdf_out(strOutputFile.c_str(), NcFile::Replace);

	// Output coordinates
	NcDim * dimLat = ncdf_out.add_dim("lat", nLat);
	NcDim * dimLon = ncdf_out.add_dim("lon", nLon);

	NcVar * varLat = ncdf_out.add_var("lat", ncDouble, dimLat);
	varLat->set_cur((long)0);
	varLat->put(&(param.vecNode[0]), nLat);

	NcVar * varLon = ncdf_out.add_var("lon", ncDouble, dimLon);
	varLon->set_cur((long)0);
	varLon->put(&(dLon[0]), nLon);

	// Generate topography
	DataMatrix<double> dTopo;
	dTopo.Initialize(nLat, nLon);

	double dK = static_cast<double>(nK);
	double dLpow = static_cast<double>(nLpow);

	double dA = 6.37122e6;
	double dX = 500.0;
	double dLatM = 0.0;
	double dLonM = M_PI / 4.0;
	double dD = 5000.0;
	double dH0 = 1.0;
	double dXiM = 4000.0;

	for (int j = 0; j < nLat; j++) {
	for (int i = 0; i < nLon; i++) {

		// Great circle distance
		double dR = dA / dX * acos(sin(dLatM) * sin(dLat[j])
			+ cos(dLatM) * cos(dLat[j]) * cos(dLon[i] - dLonM));

		double dCosXi = 1.0; //cos(M_PI * dR / dXiM);

		dTopo[j][i] = dH0 * exp(- dR * dR / (dD * dD))
			* dCosXi * dCosXi;
	}
	}

	// Write topography
	NcVar * varZs = ncdf_out.add_var("Zs", ncDouble, dimLat, dimLon);
	varZs->set_cur(0, 0);
	varZs->put(&(dTopo[0][0]), nLat, nLon);

	AnnounceEndBlock("Done");
	Announce("Completed successfully!");
	AnnounceBanner();

} catch(Exception & e) {
	Announce(e.ToString().c_str());
}
	MPI_Finalize();
}
void GenerateEvolutionMatrix(
	int nK,
	const Parameters & param,
	DataMatrix<double> & matM,
	DataMatrix<double> & matB
) {
	int nMatrixSize = 5 * param.nPhiElements - 1;

	matM.Initialize(nMatrixSize, nMatrixSize);
	matB.Initialize(nMatrixSize, nMatrixSize);

	// Radius of the Earth
	const double ParamEarthRadius = 6.37122e6;

	// Ideal gas constant
	const double ParamRd = 287.0;

	// Inverse Rossby number
	double dInvRo =
		2.0 * ParamEarthRadius * param.dOmega * param.dXscale / param.dU0;

	// Scale height
	double dH = ParamRd * param.dT0 / param.dG;

	// Froude number
	double dFr = param.dU0 / sqrt(param.dG * dH);

	// Squared Froude number
	double dFr2 = dFr * dFr;

	// Aspect ratio
	double dAs = dH / (ParamEarthRadius / param.dXscale);

	// Velocity ratio
	double dAv = dAs;

	// Wave number
	double dK2 = static_cast<double>(nK * nK);

	// Gamma
	double dInvGamma = 1.0 / param.dGamma;

	// Grid spacing
	double dDeltaPhi = param.vecNode[1] - param.vecNode[0];

	// Loop through all elements
	for (int j = 0; j < param.nPhiElements; j++) {

		// Index of the start of this block
		int ix = 4 * j;
		int ixU = ix;
		int ixP = ix + 1;
		int ixW = ix + 2;
		int ixR = ix + 3;

		int ixVL = 4 * param.nPhiElements + j - 1;
		int ixVR = 4 * param.nPhiElements + j;

		// Phi at this node
		double dPhi = param.vecNode[j];

		// Cosine Phi
		double dCosPhi = cos(dPhi);

		// Sin Phi
		double dSinPhi = sin(dPhi);

		// Tan Phi
		double dTanPhi = tan(dPhi);

		// U evolution equations
		matM[ixU][ixU] = dFr2 * dCosPhi * dCosPhi;
		matM[ixP][ixU] = 1.0;

		if (j != 0) {
			matM[ixVL][ixU] = - 0.5 * dFr2 * (2.0 + dInvRo) * dSinPhi * dCosPhi;
		}
		if (j != param.nPhiElements - 1) {
			matM[ixVR][ixU] = - 0.5 * dFr2 * (2.0 + dInvRo) * dSinPhi * dCosPhi;
		}

		// V evolution equations
		if (j != 0) {
			int ixV = ixVL;

			int ixUL = ix - 4;
			int ixPL = ix - 3;
			int ixRL = ix - 1;

			int ixUR = ix;
			int ixPR = ix + 1;
			int ixRR = ix + 3;

			double dPhiS = param.vecEdge[j];
			double dSinPhiS = sin(dPhiS);
			double dCosPhiS = cos(dPhiS);

			matM[ixUL][ixV] = 0.5 * dFr2 * (2.0 + dInvRo) * dSinPhiS * dCosPhiS;
			matM[ixUR][ixV] = 0.5 * dFr2 * (2.0 + dInvRo) * dSinPhiS * dCosPhiS;

			matM[ixV][ixV] = - dK2 * dFr2;

			matM[ixPL][ixV] =
				- 0.5 * dFr2 * (1.0 + dInvRo) * dSinPhiS * dCosPhiS
				- 1.0 / dDeltaPhi;
			matM[ixPR][ixV] =
				- 0.5 * dFr2 * (1.0 + dInvRo) * dSinPhiS * dCosPhiS
				+ 1.0 / dDeltaPhi;

			matM[ixRL][ixV] = 0.5 * dFr2 * (1.0 + dInvRo) * dSinPhiS * dCosPhiS;
			matM[ixRR][ixV] = 0.5 * dFr2 * (1.0 + dInvRo) * dSinPhiS * dCosPhiS;
		}

		// P evolution equations
		matM[ixU][ixP] = 1.0;
		matM[ixR][ixP] = 1.0;

		if (j != 0) {
			matM[ixVL][ixP] =
				- 0.5 * dFr2 * (1.0 + dInvRo) * dSinPhi * dCosPhi
				- 0.5 * dTanPhi
				- 1.0 / dDeltaPhi;
		}
		if (j != param.nPhiElements - 1) {
			matM[ixVR][ixP] =
				- 0.5 * dFr2 * (1.0 + dInvRo) * dSinPhi * dCosPhi
				- 0.5 * dTanPhi
				+ 1.0 / dDeltaPhi;
		}

		// W evolution equation
		matM[ixW][ixW] = - dK2 * dAs * dAv * dFr2;
		matM[ixR][ixW] = 1.0;

		// R evolution equation
		matM[ixP][ixR] = dInvGamma / (1.0 - dInvGamma);
		matM[ixW][ixR] = dAv / dAs;
		matM[ixR][ixR] = - 1.0 / (1.0 - dInvGamma);

		if (j != 0) {
			matM[ixVL][ixR] = 0.5 * dFr2 * (1.0 + dInvRo) * dSinPhi * dCosPhi;
		}
		if (j != param.nPhiElements - 1) {
			matM[ixVR][ixR] = 0.5 * dFr2 * (1.0 + dInvRo) * dSinPhi * dCosPhi;
		}

		// B matrix coefficients
		matB[ixP][ixW] = -1.0;
		matB[ixW][ixP] = -1.0;
	}
}
int main(int argc, char ** argv) {

try {

	// Parameters
	Parameters param;

	// Output filename
	std::string strOutputFile;

	// Horizontal minimum wave number
	int nKmin;

	// Horizontal maximum wave number
	int nKmax;

	// Parse the command line
	BeginCommandLine()
		CommandLineInt(param.nPhiElements, "n", 40);
		CommandLineInt(nKmin, "kmin", 1);
		CommandLineInt(nKmax, "kmax", 20);
		CommandLineDouble(param.dXscale, "X", 1.0);
		CommandLineDouble(param.dT0, "T0", 300.0);
		CommandLineDouble(param.dU0, "U0", 20.0);
		CommandLineDouble(param.dG, "G", 9.80616);
		CommandLineDouble(param.dOmega, "omega", 7.29212e-5);
		CommandLineDouble(param.dGamma, "gamma", 1.4);
		CommandLineString(strOutputFile, "out", "wave.nc");

		ParseCommandLine(argc, argv);
	EndCommandLine(argv)

	AnnounceBanner();

	// Generate latitude values
	param.GenerateLatituteArray(param.nPhiElements);

	// Open NetCDF file
	NcFile ncdf_out(strOutputFile.c_str(), NcFile::Replace);

	NcDim *dimK = ncdf_out.add_dim("k", nKmax - nKmin + 1);
	NcDim *dimLat = ncdf_out.add_dim("lat", param.nPhiElements);
	NcDim *dimEig = ncdf_out.add_dim("eig", param.nPhiElements);

	// Write parameters and latitudes to file
	param.WriteToNcFile(ncdf_out, dimLat, dimLatS);

	// Wave numbers 
	NcVar *varK = ncdf_out.add_var("k", ncInt, dimK);

	DataVector<int> vecK;
	vecK.Initialize(nKmax - nKmin + 1);
	for (int nK = nKmin; nK <= nKmax; nK++) { 
		vecK[nK - nKmin] = nK;
	}

	varK->set_cur((long)0);
	varK->put(vecK, nKmax - nKmin + 1);

	// Eigenvalues
	NcVar *varMR = ncdf_out.add_var("mR", ncDouble, dimK, dimEig);
	NcVar *varMI = ncdf_out.add_var("mI", ncDouble, dimK, dimEig);

	NcVar *varUR = ncdf_out.add_var("uR", ncDouble, dimK, dimEig, dimLat);
	NcVar *varUI = ncdf_out.add_var("uI", ncDouble, dimK, dimEig, dimLat);

	NcVar *varVR = ncdf_out.add_var("vR", ncDouble, dimK, dimEig, dimLatS);
	NcVar *varVI = ncdf_out.add_var("vI", ncDouble, dimK, dimEig, dimLatS);

	NcVar *varPR = ncdf_out.add_var("pR", ncDouble, dimK, dimEig, dimLat);
	NcVar *varPI = ncdf_out.add_var("pI", ncDouble, dimK, dimEig, dimLat);

	NcVar *varWR = ncdf_out.add_var("wR", ncDouble, dimK, dimEig, dimLat);
	NcVar *varWI = ncdf_out.add_var("wI", ncDouble, dimK, dimEig, dimLat);

	NcVar *varRhoR = ncdf_out.add_var("rhoR", ncDouble, dimK, dimEig, dimLat);
	NcVar *varRhoI = ncdf_out.add_var("rhoI", ncDouble, dimK, dimEig, dimLat);

	// Allocate temporary arrays
	DataVector<double> dUR;
	dUR.Initialize(param.nPhiElements);

	DataVector<double> dUI;
	dUI.Initialize(param.nPhiElements);

	DataVector<double> dVR;
	dVR.Initialize(param.nPhiElements-1);

	DataVector<double> dVI;
	dVI.Initialize(param.nPhiElements-1);

	DataVector<double> dPR;
	dPR.Initialize(param.nPhiElements);

	DataVector<double> dPI;
	dPI.Initialize(param.nPhiElements);

	DataVector<double> dWR;
	dWR.Initialize(param.nPhiElements);

	DataVector<double> dWI;
	dWI.Initialize(param.nPhiElements);

	DataVector<double> dRhoR;
	dRhoR.Initialize(param.nPhiElements);

	DataVector<double> dRhoI;
	dRhoI.Initialize(param.nPhiElements);

	// Loop over all horizontal wave numbers
	for (int nK = nKmin; nK <= nKmax; nK++) {

		// Build matrices
		char szMessage[100];
		sprintf(szMessage, "Building evolution matrices (k = %i)", nK);
		AnnounceStartBlock(szMessage);

		DataMatrix<double> matM;
		DataMatrix<double> matB;

		GenerateEvolutionMatrix(nK, param, matM, matB);

		AnnounceEndBlock("Done");

		// Solve the matrices
		AnnounceStartBlock("Solving evolution matrices");

		DataVector<double> vecAlphaR;
		DataVector<double> vecAlphaI;
		DataVector<double> vecBeta;
		DataMatrix<double> matVR;

		vecAlphaR.Initialize(matM.GetRows());
		vecAlphaI.Initialize(matM.GetRows());
		vecBeta  .Initialize(matM.GetRows());
		matVR    .Initialize(matM.GetRows(), matM.GetColumns());

		SolveEvolutionMatrix(
			matM,
			matB,
			vecAlphaR,
			vecAlphaI,
			vecBeta,
			matVR);

		// Sort eigenvalues
		std::multimap<double, int> mapSortedRows;
		for (int i = 0; i < vecBeta.GetRows(); i++) {
			if (vecBeta[i] != 0.0) {

				double dLambdaR = vecAlphaR[i] / vecBeta[i];
				double dLambdaI = vecAlphaI[i] / vecBeta[i];

				double dMR = dLambdaI;
				double dMI = - dLambdaR - 1.0;

				double dEvalMagnitude = fabs(dMR);

				//printf("\n%1.5e %1.5e ", dMR, dMI);

				// Purely imaginary eigenvalue
				if (dMR == 0.0) {
					// Wave must decay with height
					if (dMI < 0.0) {
						continue;
					}

				// Complex-conjugate pair of eigenvalues
				} else {
					// Phase propagation must be downward, and energy
					// propagation upwards
					if (dMR < 0.0) {
						continue;
					}
				}

				//printf("(OK)");

				mapSortedRows.insert(
					std::pair<double, int>(dEvalMagnitude, i));

				// Only store one entry for complex-conjugate pairs
				if (vecAlphaI[i] != 0.0) {
					i++;
				}
			}
		}

		Announce("%i eigenmodes found to satisfy entropy condition",
			mapSortedRows.size());
/*
		if (mapSortedRows.size() != param.nPhiElements) {
			_EXCEPTIONT("Mismatch between eigenmode count and latitude count");
		}
*/
		AnnounceEndBlock("Done");

		// Write the matrices to a file
		AnnounceStartBlock("Writing results");

		int iKix = nK - nKmin;
		int iWave = 0;
		std::map<double, int>::const_iterator it;
		for (it = mapSortedRows.begin(); it != mapSortedRows.end(); it++) {
			int i = it->second;

			double dLambdaR = vecAlphaR[i] / vecBeta[i];
			double dLambdaI = vecAlphaI[i] / vecBeta[i];

			double dMR = dLambdaI;
			double dMI = - dLambdaR - 1.0;

			// Dump eigenvalue to NetCDF file
			varMR->set_cur(iKix, iWave);
			varMR->put(&dMR, 1, 1);

			varMI->set_cur(iKix, iWave);
			varMI->put(&dMI, 1, 1);

			// Store real part of eigenfunction
			for (int j = 0; j < param.nPhiElements; j++) {
				dUR  [j] = matVR[i][4*j  ];
				dPR  [j] = matVR[i][4*j+1];
				dWR  [j] = matVR[i][4*j+2];
				dRhoR[j] = matVR[i][4*j+3];
			}
			for (int j = 0; j < param.nPhiElements-1; j++) {
				dVR[j] = matVR[i][4 * param.nPhiElements + j];
			}

			// Complex eigenvalue / eigenfunction pair
			if (dLambdaI != 0.0) {

				// Eigenvalue Lambda is complex conjugate
				dMR = -dMR;

				// Dump eigenvalue to NetCDF file
				varMR->set_cur(iKix, iWave+1);
				varMR->put(&dMR, 1, 1);

				varMI->set_cur(iKix, iWave+1);
				varMI->put(&dMI, 1, 1);

				// Store imaginary component of vector
				for (int j = 0; j < param.nPhiElements; j++) {
					dUI  [j] = matVR[i+1][4*j  ];
					dPI  [j] = matVR[i+1][4*j+1];
					dWI  [j] = matVR[i+1][4*j+2];
					dRhoI[j] = matVR[i+1][4*j+3];
				}
				for (int j = 0; j < param.nPhiElements-1; j++) {
					dVI[j] = matVR[i+1][4 * param.nPhiElements + j];
				}

			// Real eigenvalue / eigenvector pair
			} else {
				dUI.Zero();
				dPI.Zero();
				dWI.Zero();
				dRhoI.Zero();
				dVI.Zero();
			}

			// Dump the first eigenfunction to the file
			varUR->set_cur(iKix, iWave, 0);
			varUR->put(dUR, 1, 1, param.nPhiElements);

			varVR->set_cur(iKix, iWave, 0);
			varVR->put(dVR, 1, 1, param.nPhiElements-1);

			varPR->set_cur(iKix, iWave, 0);
			varPR->put(dPR, 1, 1, param.nPhiElements);

			varWR->set_cur(iKix, iWave, 0);
			varWR->put(dWR, 1, 1, param.nPhiElements);

			varRhoR->set_cur(iKix, iWave, 0);
			varRhoR->put(dRhoR, 1, 1, param.nPhiElements);

			varUI->set_cur(iKix, iWave, 0);
			varUI->put(dUI, 1, 1, param.nPhiElements);

			varVI->set_cur(iKix, iWave, 0);
			varVI->put(dVI, 1, 1, param.nPhiElements-1);

			varPI->set_cur(iKix, iWave, 0);
			varPI->put(dPI, 1, 1, param.nPhiElements);

			varWI->set_cur(iKix, iWave, 0);
			varWI->put(dWI, 1, 1, param.nPhiElements);

			varRhoI->set_cur(iKix, iWave, 0);
			varRhoI->put(dRhoI, 1, 1, param.nPhiElements);

			// Complex eigenvalue / eigenvector pair
			if (dLambdaI != 0.0) {
				for (int j = 0; j < param.nPhiElements; j++) {
					dUI  [j] = - dUI  [j];
					dPI  [j] = - dPI  [j];
					dWI  [j] = - dWI  [j];
					dRhoI[j] = - dRhoI[j];
				}
				for (int j = 0; j < param.nPhiElements-1; j++) {
					dVI[j] = - dVI[j];
				}

				varUR->set_cur(iKix, iWave+1, 0);
				varUR->put(dUR, 1, 1, param.nPhiElements);

				varVR->set_cur(iKix, iWave+1, 0);
				varVR->put(dVR, 1, 1, param.nPhiElements-1);

				varPR->set_cur(iKix, iWave+1, 0);
				varPR->put(dPR, 1, 1, param.nPhiElements);

				varWR->set_cur(iKix, iWave+1, 0);
				varWR->put(dWR, 1, 1, param.nPhiElements);

				varRhoR->set_cur(iKix, iWave+1, 0);
				varRhoR->put(dRhoR, 1, 1, param.nPhiElements);

				varUI->set_cur(iKix, iWave+1, 0);
				varUI->put(dUI, 1, 1, param.nPhiElements);

				varVI->set_cur(iKix, iWave+1, 0);
				varVI->put(dVI, 1, 1, param.nPhiElements-1);

				varPI->set_cur(iKix, iWave+1, 0);
				varPI->put(dPI, 1, 1, param.nPhiElements);

				varWI->set_cur(iKix, iWave+1, 0);
				varWI->put(dWI, 1, 1, param.nPhiElements);

				varRhoI->set_cur(iKix, iWave+1, 0);
				varRhoI->put(dRhoI, 1, 1, param.nPhiElements);
			}

			// Increment wave index
			iWave++;
			if (dLambdaI != 0.0) {
				iWave++;
			}
		}

		AnnounceEndBlock("Done");

		AnnounceBanner();
	}

} catch(Exception & e) {
	Announce(e.ToString().c_str());
}
}
LogisticRegression::LogisticRegression(DataMatrix<double> ddata, std::vector<double> iinit, double aalpha):
    data(ddata), init(iinit), alpha(aalpha), nrows(ddata.getRows()), ncols(ddata.getCols()){
    if(init.size() != (ncols-1))
        std::cerr<<"Error!"<<std::endl;
}
float_t OperationNaiveEvalHessianModFundamentalSpline::evalHessian(
  const DataVector& alpha, const DataVector& point,
  DataVector& gradient, DataMatrix& hessian) {
  const size_t n = storage->size();
  const size_t d = storage->dim();
  float_t result = 0.0;

  gradient.resize(storage->dim());
  gradient.setAll(0.0);

  hessian = DataMatrix(d, d);
  hessian.setAll(0.0);

  DataVector curGradient(d);
  DataMatrix curHessian(d, d);

  for (size_t i = 0; i < n; i++) {
    const GridIndex& gp = *(*storage)[i];
    float_t curValue = 1.0;
    curGradient.setAll(alpha[i]);
    curHessian.setAll(alpha[i]);

    for (size_t t = 0; t < d; t++) {
      const float_t val1d = base.eval(gp.getLevel(t), gp.getIndex(t), point[t]);
      const float_t dx1d = base.evalDx(gp.getLevel(t), gp.getIndex(t),
                                       point[t]);
      const float_t dxdx1d = base.evalDxDx(gp.getLevel(t), gp.getIndex(t), point[t]);

      curValue *= val1d;

      for (size_t t2 = 0; t2 < d; t2++) {
        if (t2 == t) {
          curGradient[t2] *= dx1d;

          for (size_t t3 = 0; t3 < d; t3++) {
            if (t3 == t) {
              curHessian(t2, t3) *= dxdx1d;
            } else {
              curHessian(t2, t3) *= dx1d;
            }
          }
        } else {
          curGradient[t2] *= val1d;

          for (size_t t3 = 0; t3 < d; t3++) {
            if (t3 == t) {
              curHessian(t2, t3) *= dx1d;
            } else {
              curHessian(t2, t3) *= val1d;
            }
          }
        }
      }
    }

    result += alpha[i] * curValue;
    gradient.add(curGradient);
    hessian.add(curHessian);
  }

  return result;
}
int main(int argc, char** argv) {

	NcError error(NcError::verbose_nonfatal);

try {

	// Input file
	std::string strInputFile;

	// Input file list
	std::string strInputFileList;

	// Input file format
	std::string strInputFormat;

	// NetCDF file containing latitude and longitude arrays
	std::string strLatLonFile;

	// Output file (NetCDF)
	std::string strOutputFile;

	// Output variable name
	std::string strOutputVariable;

	// Column in which the longitude index appears
	int iLonIxCol;

	// Column in which the latitude index appears
	int iLatIxCol;

	// Begin latitude
	double dLatBegin;

	// End latitude
	double dLatEnd;

	// Begin longitude
	double dLonBegin;

	// End longitude
	double dLonEnd;

	// Number of latitudes in output
	int nLat;

	// Number of longitudes in output
	int nLon;

	// Parse the command line
	BeginCommandLine()
		CommandLineString(strInputFile, "in", "");
		CommandLineString(strInputFileList, "inlist", "");
		CommandLineStringD(strInputFormat, "in_format", "std", "(std|visit)");
		CommandLineString(strOutputFile, "out", "");
		CommandLineString(strOutputVariable, "outvar", "density");
		CommandLineInt(iLonIxCol, "iloncol", 8);
		CommandLineInt(iLatIxCol, "ilatcol", 9);
		CommandLineDouble(dLatBegin, "lat_begin", -90.0);
		CommandLineDouble(dLatEnd, "lat_end", 90.0);
		CommandLineDouble(dLonBegin, "lon_begin", 0.0);
		CommandLineDouble(dLonEnd, "lon_end", 360.0);
		CommandLineInt(nLat, "nlat", 180);
		CommandLineInt(nLon, "nlon", 360);

		ParseCommandLine(argc, argv);
	EndCommandLine(argv)

	AnnounceBanner();

	// Check input
	if ((strInputFile == "") && (strInputFileList == "")) {
		_EXCEPTIONT("No input file (--in) or (--inlist) specified");
	}
	if ((strInputFile != "") && (strInputFileList != "")) {
		_EXCEPTIONT("Only one input file (--in) or (--inlist) allowed");
	}
	if (strInputFormat != "std") {
		_EXCEPTIONT("UNIMPLEMENTED:  Only \"--in_format std\" supported");
	}

	// Check output
	if (strOutputFile == "") {
		_EXCEPTIONT("No output file (--out) specified");
	}

	// Check output variable
	if (strOutputVariable == "") {
		_EXCEPTIONT("No output variable name (--outvar) specified");
	}

	// Number of latitudes and longitudes
	if (nLat == 0) {
		_EXCEPTIONT("UNIMPLEMENTED: --nlat must be specified currently");
	}
	if (nLon == 0) {
		_EXCEPTIONT("UNIMPLEMENTED: --nlon must be specified currently");
	}

	// Input file list
	std::vector<std::string> vecInputFiles;

	if (strInputFile != "") {
		vecInputFiles.push_back(strInputFile);
	}
	if (strInputFileList != "") {
		GetInputFileList(strInputFileList, vecInputFiles);
	}

	int nFiles = vecInputFiles.size();

	// Density
	DataMatrix<int> nCounts;
	nCounts.Initialize(nLat, nLon);

	// Loop through all files in list
	AnnounceStartBlock("Processing files");

	std::string strBuffer;
	strBuffer.reserve(1024);

	for (int f = 0; f < nFiles; f++) {
		Announce("File \"%s\"", vecInputFiles[f].c_str());

		FILE * fp = fopen(vecInputFiles[f].c_str(), "r");
		if (fp == NULL) {
			_EXCEPTION1("Unable to open input file \"%s\"",
				vecInputFiles[f].c_str());
		}

		for (;;) {

			// Read in the next line
			fgets(&(strBuffer[0]), 1024, fp);

			int nLength = strlen(&(strBuffer[0]));

			// Check for end of file
			if (feof(fp)) {
				break;
			}

			// Check for comment line
			if (strBuffer[0] == '#') {
				continue;
			}

			// Check for new storm
			if (strncmp(&(strBuffer[0]), "start", 5) == 0) {
				continue;
			}

			// Parse line
			double dLon;
			double dLat;

			int iCol = 0;
			int iLast = 0;

			bool fWhitespace = true;

			for (int i = 0; i <= nLength; i++) {
				if ((strBuffer[i] == ' ') ||
					(strBuffer[i] == ',') ||
					(strBuffer[i] == '\t') ||
					(strBuffer[i] == '\0')
				) {
					if (!fWhitespace) {
						if (iCol == iLonIxCol) {
							strBuffer[i] = '\0';
							dLon = atof(&(strBuffer[iLast]));
						}
						if (iCol == iLatIxCol) {
							strBuffer[i] = '\0';
							dLat = atof(&(strBuffer[iLast]));
						}
					}

					fWhitespace = true;

				} else {
					if (fWhitespace) {
						iLast = i;
						iCol++;
					}
					fWhitespace = false;
				}
			}

			// Latitude and longitude index
			int iLon =
				static_cast<int>(static_cast<double>(nLon)
					* (dLon - dLonBegin) / (dLonEnd - dLonBegin));
			int iLat =
				static_cast<int>(static_cast<double>(nLat)
					* (dLat - dLatBegin) / (dLatEnd - dLatBegin));

			if (iLon == (-1)) {
				iLon = 0;
			}
			if (iLon == nLon) {
				iLon = nLon - 1;
			}
			if (iLat == (-1)) {
				iLat = 0;
			}
			if (iLat == nLat) {
				iLat = nLat - 1;
			}

			if ((iLat < 0) || (iLat >= nLat)) {
				_EXCEPTION1("Latitude index (%i) out of range", iLat);
			}
			if ((iLon < 0) || (iLon >= nLon)) {
				_EXCEPTION1("Longitude index (%i) out of range", iLon);
			}

			nCounts[iLat][iLon]++;
		}

		fclose(fp);
	}

	AnnounceEndBlock("Done");

	// Output results
	AnnounceStartBlock("Output results");

	// Load the netcdf output file
	NcFile ncOutput(strOutputFile.c_str(), NcFile::Replace);
	if (!ncOutput.is_valid()) {
		_EXCEPTION1("Unable to open output file \"%s\"",
			strOutputFile.c_str());
	}

	// Create output
	NcDim * dimLat = ncOutput.add_dim("lat", nLat);
	NcDim * dimLon = ncOutput.add_dim("lon", nLon);

	NcVar * varLat = ncOutput.add_var("lat", ncDouble, dimLat);
	NcVar * varLon = ncOutput.add_var("lon", ncDouble, dimLon);

	varLat->add_att("units", "degrees_north");
	varLon->add_att("units", "degrees_east");

	DataVector<double> dLat(nLat);
	DataVector<double> dLon(nLon);

	for (int j = 0; j < nLat; j++) {
		dLat[j] = dLatBegin
			+ (dLatEnd - dLatBegin)
				* (static_cast<double>(j) + 0.5)
				/ static_cast<double>(nLat);
	}
	for (int i = 0; i < nLon; i++) {
		dLon[i] = dLonBegin
			+ (dLonEnd - dLonBegin)
			* (static_cast<double>(i) + 0.5)
			/ static_cast<double>(nLon);
	}

	varLat->put(&(dLat[0]), nLat);
	varLon->put(&(dLon[0]), nLon);

	// Output counts
	NcVar * varCount =
		ncOutput.add_var(
			strOutputVariable.c_str(),
			ncInt,
			dimLat,
			dimLon);

	varCount->put(&(nCounts[0][0]), nLat, nLon);

	ncOutput.close();

	AnnounceEndBlock("Done");

	AnnounceBanner();

} catch(Exception & e) {
	Announce(e.ToString().c_str());
}
}