Skip to content

Commit

Permalink
add pca to swig for geodawb
Browse files Browse the repository at this point in the history
  • Loading branch information
lixun910 committed May 19, 2017
1 parent 0959ecd commit 979548c
Show file tree
Hide file tree
Showing 9 changed files with 3,409 additions and 835 deletions.
7 changes: 7 additions & 0 deletions swig/build.sh
@@ -0,0 +1,7 @@

cp OGRLayerProxy.cpp ../ShapeOperations/OGRLayerProxy.cpp

swig -python -c++ -threads proxy.i

CFLAGS='-Wall -O0 -DDEBUG' python setup_centos.py build_ext --inplace --force

51 changes: 51 additions & 0 deletions swig/geoda.py
Expand Up @@ -96,6 +96,53 @@ def __iter__(self): return self
SwigPyIterator_swigregister = _geoda.SwigPyIterator_swigregister
SwigPyIterator_swigregister(SwigPyIterator)

class VecFloat(_object):
__swig_setmethods__ = {}
__setattr__ = lambda self, name, value: _swig_setattr(self, VecFloat, name, value)
__swig_getmethods__ = {}
__getattr__ = lambda self, name: _swig_getattr(self, VecFloat, name)
__repr__ = _swig_repr
def iterator(self): return _geoda.VecFloat_iterator(self)
def __iter__(self): return self.iterator()
def __nonzero__(self): return _geoda.VecFloat___nonzero__(self)
def __bool__(self): return _geoda.VecFloat___bool__(self)
def __len__(self): return _geoda.VecFloat___len__(self)
def pop(self): return _geoda.VecFloat_pop(self)
def __getslice__(self, *args): return _geoda.VecFloat___getslice__(self, *args)
def __setslice__(self, *args): return _geoda.VecFloat___setslice__(self, *args)
def __delslice__(self, *args): return _geoda.VecFloat___delslice__(self, *args)
def __delitem__(self, *args): return _geoda.VecFloat___delitem__(self, *args)
def __getitem__(self, *args): return _geoda.VecFloat___getitem__(self, *args)
def __setitem__(self, *args): return _geoda.VecFloat___setitem__(self, *args)
def append(self, *args): return _geoda.VecFloat_append(self, *args)
def empty(self): return _geoda.VecFloat_empty(self)
def size(self): return _geoda.VecFloat_size(self)
def clear(self): return _geoda.VecFloat_clear(self)
def swap(self, *args): return _geoda.VecFloat_swap(self, *args)
def get_allocator(self): return _geoda.VecFloat_get_allocator(self)
def begin(self): return _geoda.VecFloat_begin(self)
def end(self): return _geoda.VecFloat_end(self)
def rbegin(self): return _geoda.VecFloat_rbegin(self)
def rend(self): return _geoda.VecFloat_rend(self)
def pop_back(self): return _geoda.VecFloat_pop_back(self)
def erase(self, *args): return _geoda.VecFloat_erase(self, *args)
def __init__(self, *args):
this = _geoda.new_VecFloat(*args)
try: self.this.append(this)
except: self.this = this
def push_back(self, *args): return _geoda.VecFloat_push_back(self, *args)
def front(self): return _geoda.VecFloat_front(self)
def back(self): return _geoda.VecFloat_back(self)
def assign(self, *args): return _geoda.VecFloat_assign(self, *args)
def resize(self, *args): return _geoda.VecFloat_resize(self, *args)
def insert(self, *args): return _geoda.VecFloat_insert(self, *args)
def reserve(self, *args): return _geoda.VecFloat_reserve(self, *args)
def capacity(self): return _geoda.VecFloat_capacity(self)
__swig_destroy__ = _geoda.delete_VecFloat
__del__ = lambda self : None;
VecFloat_swigregister = _geoda.VecFloat_swigregister
VecFloat_swigregister(VecFloat)

class VecString(_object):
__swig_setmethods__ = {}
__setattr__ = lambda self, name, value: _swig_setattr(self, VecString, name, value)
Expand Down Expand Up @@ -457,6 +504,10 @@ def Hinge15(*args):
def Hinge30(*args):
return _geoda.Hinge30(*args)
Hinge30 = _geoda.Hinge30

def PCA(*args):
return _geoda.PCA(*args)
PCA = _geoda.PCA
# This file is compatible with both classic and new-style classes.


7 changes: 7 additions & 0 deletions swig/install.py
@@ -0,0 +1,7 @@

cp OGRLayerProxy.cpp ../ShapeOperations/OGRLayerProxy.cpp

rm -rf build/

python setup.py install

131 changes: 131 additions & 0 deletions swig/proxy.cpp
Expand Up @@ -3,13 +3,16 @@
#include <set>
#include <utility>
#include <algorithm>
#include <sstream>
#include <stdio.h>

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif

#include <wx/tokenzr.h>

#include "../ShapeOperations/GwtWeight.h"
#include "../ShapeOperations/GalWeight.h"
#include "../ShapeOperations/PolysToContigWeights.h"
Expand All @@ -19,6 +22,7 @@
#include "../Explore/CatClassification.h"
#include "../SpatialIndAlgs.h"
#include "../GenUtils.h"
#include "../pca.h"

#include "proxy.h"

Expand Down Expand Up @@ -513,3 +517,130 @@ Hinge30(
) {
return Hinge1530(1, num_obs, data, num_categories, useScientificNotation, breaks);
}


///////////////////////////////////////////////////////////////////////////////
//
// std::vector<int> clusters
///////////////////////////////////////////////////////////////////////////////
std::string
PCA(
std::vector<float>& x,
std::vector<std::string>& x_names,
int _nrows,
int _ncols,
int _is_corr,
int _is_center,
int _is_scale
) {
Pca pca;

bool is_corr = _is_corr == 0 ? false : true;
bool is_center = _is_center == 0 ? false : true;
bool is_scale = _is_scale == 0 ? false : true;

int rtn = pca.Calculate(x, _nrows, _ncols, is_corr, is_center, is_scale);

if ( 0 != rtn ) {
// error of PCA
return "";
}

vector<float> sd = pca.sd();
vector<float> prop_of_var = pca.prop_of_var();
vector<float> cum_prop = pca.cum_prop();
vector<float> scores = pca.scores();

vector<unsigned int> el_cols = pca.eliminated_columns();

float kaiser = pca.kaiser();
float thresh95 = pca.thresh95();

unsigned int ncols = pca.ncols();
unsigned int nrows = pca.nrows();

int max_sel_name_len = 0;

wxString method = pca.method();

wxString pca_log;
//pca_log << "\n\nPCA method: " << method;

pca_log << "\n\nStandard deviation:\n";
for (int i=0; i<sd.size();i++) pca_log << sd[i] << " ";

pca_log << "\n\nProportion of variance:\n";
for (int i=0; i<prop_of_var.size();i++) pca_log << prop_of_var[i] << " ";

pca_log << "\n\nCumulative proportion:\n";
for (int i=0; i<cum_prop.size();i++) pca_log << cum_prop[i] << " ";

pca_log << "\n\nKaiser criterion: " << kaiser;
pca_log << "\n\n95% threshold criterion: " << thresh95;

pca_log << "\n\nEigenvalues:\n";
std::stringstream ss;
ss << pca.eigen_values;
pca_log << ss.str();

//pca_log << pca.eigen_values;
pca_log << "\n\nEigenvectors:\n";

std::stringstream ss1;
ss1 << pca.eigen_vectors;
wxString loadings = ss1.str();
wxStringTokenizer tokenizer(loadings, "\n");
wxArrayString items;
bool header = false;
while ( tokenizer.HasMoreTokens() )
{
wxString token = tokenizer.GetNextToken();
// process token here
items.Add(token);

if (header == false) {
pca_log << wxString::Format("%-*s", max_sel_name_len+4, "");
int n_len = token.length();
int pos = 0;
bool start = false;
int sub_len = 0;
int pc_idx = 1;

while (pos < n_len){
if ( start && sub_len > 0 && (token[pos] == ' ' || pos == n_len-1) ) {
// end of a number
pca_log << wxString::Format("%*s%d", sub_len-1, "PC", pc_idx++);
sub_len = 1;
start = false;
} else {
if (!start && token[pos] != ' ') {
start = true;
}
sub_len += 1;
}
pos += 1;
}
header = true;
pca_log << "\n";
}
}

for (int k=0; k<items.size();k++) {
pca_log << wxString::Format("%-*s", max_sel_name_len+4, wxString(x_names[k])) << items[k] << "\n";
}

unsigned int row_lim;
unsigned int col_lim;

if (scores.size() != nrows * ncols) {
row_lim = (nrows < ncols)? nrows : ncols,
col_lim = (ncols < nrows)? ncols : nrows;
} else {
row_lim = nrows;
col_lim = ncols;
}

return string(pca_log.mb_str());
}


11 changes: 11 additions & 0 deletions swig/proxy.h
Expand Up @@ -39,3 +39,14 @@ Hinge30(
bool useScientificNotation,
std::vector<double>& breaks // return results
);

std::string
PCA(
std::vector<float>& x,
std::vector<std::string>& x_names,
int nrows,
int ncols,
int is_corr,
int is_center,
int is_scale
);
11 changes: 11 additions & 0 deletions swig/proxy.i
Expand Up @@ -4,6 +4,7 @@

%include "std_vector.i"
namespace std {
%template(VecFloat) vector<float>;
%template(VecString) vector<string>;
%template(VecDouble) vector<double>;
%template(VecVecDouble) vector< vector<double> >;
Expand Down Expand Up @@ -58,3 +59,13 @@ Hinge30(
std::vector<double>& breaks // return results
);

std::string
PCA(
std::vector<float>& x,
std::vector<std::string>& x_names,
int nrows,
int ncols,
int is_corr,
int is_center,
int is_scale
);

0 comments on commit 979548c

Please sign in to comment.