Python34 NMEA sentences put into xlsx using xlsxwriter - arrays

I'm working on an nmea sentence project where I get a txt file with nmea sentences delimited by commas. I'm trying to use xlsxwriter to write the results into excel. The results I want are having the timestamp,latitude, longitude and altitude printed in rows that correspond to each other...but I keep getting the first iteration of my 'query' written out five times before the other iterations are written into xlsx. I know there must be a simple solution to this..can you tell me where I'm going wrong?
This is the beginning of my script so you have a full picture of what is going on
import os
import csv
from csv import *
import numpy
import matplotlib
from numpy import *
from matplotlib import *
import matplotlib.pyplot as plt
from matplotlib.pylab import *
import numpy as np
#to export to excel
import xlsxwriter
from xlsxwriter.workbook import Workbook
#to get the csv converter functions
import os
import subprocess
import glob
#to get the datetime functions
import datetime
from datetime import datetime
from pytz import timezone
import time
import calendar
#creates the path needed for incoming and outgoing files
path_in = 'C:/Python34/gps_txts/'
path_out = 'C:/Python34/output_files/'
#prints all the data in the file if you want
q_show_content = input('Print list of files type y:')
if q_show_content == 'y':
for root, dirs, files in os.walk(path_in):
print(root, dirs, files)
else:
print('ok')
data = [] #empty because we will store data into it
#Reads a CSV file and return it as a list of rows
def read_csv_file(filename):
"""Reads a CSV file and return it as a list of rows."""
for row in csv.reader(open(filename)):
data.append(row)
return data
#request of what file to look at
print ("- - - - - - - - - - - - -")
data_file = input('Which file do you want to look at?')
f = open(path_in + data_file)
read_it = read_csv_file(path_in + data_file)
with f as csvfile:
readCSV = csv.reader(csvfile,delimiter=',')
plots = csv.reader(csvfile, delimiter=',')
#creates the workbook
output_filename = input('output filename:')
workbook = xlsxwriter.Workbook(path_out + output_filename + '.xlsx')
worksheet = workbook.add_worksheet()
#formatting definitions
bold = workbook.add_format({'bold': True})
date_format = workbook.add_format({'num_format': "m/d/yyyy hh:mm:ss"})
#print number of rows
print ("- - - - - - - - - - - - -")
rows = len(read_it)
print (data_file, " has "+ str(rows) + " rows of data")
print ("- - - - - - - - - - - - -")
#Counts the number of times a GPS command is observed
def list_gps_commands(data):
"""Counts the number of times a GPS command is observed.
Returns a dictionary object."""
gps_cmds = dict()
for row in data:
try:
gps_cmds[row[0]] += 1
except KeyError:
gps_cmds[row[0]] = 1
return gps_cmds
print(list_gps_commands(read_it))
print ("- - - - - - - - - - - - -")
#prints all the data in the file if you want
q_show_data = input('Print data inside ' + data_file + ' type y:')
if q_show_data == 'y':
for row in read_it:
print(row)
else:
print('ok')
This is the part I'm having an issue with
#Function process_gps_data for GPS
NMI = 1852.0
def process_gps_data(data):
"""Processes GPS data, NMEA 0183 format.
Returns a tuple of arrays: latitude, longitude, velocity [km/h],
time [sec] and number of satellites.
See also: http://www.gpsinformation.org/dale/nmea.htm.
"""
latitude = []
longitude = []
altitude = []
velocity = []
timestamp = []
num_sats = []
for row in data:
if row[0] == '$GPRMC': # Valid position/time sentence
y = (float(row[3][0:2]) + float(row[3][2:])/60.0)
if row[4] == "S":
y = -y
latitude.append(y)
x = (float(row[5][0:3]) + float(row[5][3:])/60.0)
if row[6] == "W":
x = -x
longitude.append(x)
print('x,y:',x,y)
velocity.append(float(row[7])*NMI/1000.0)
gpstime = row[1][0:6] # hhmmss
gdate = row[9] # ddmmyy
gpsdate = gdate[4:6]+gdate[2:4]+gdate[0:2] # yymmdd
real_time =gpsdate + gpstime
add_date_time = datetime.strptime(real_time, "%y%m%d%H%M%S")
print(add_date_time)
timestamp.append(add_date_time)
return (array(latitude), array(longitude), array(velocity), array(timestamp))
# how to call process_gps_data()
(lati, long, v, t_stamp) = process_gps_data(data)
print ("- - - - - - - - - - - - -")
print('lati:',lati)
print ("- - - - - - - - - - - - -")
print('long:',long)
print ("- - - - - - - - - - - - -")
print('v:',v)
print ("- - - - - - - - - - - - -")
print('date:', t_stamp)
print ("- - - - - - - - - - - - -")
#sets up the header row
worksheet.write('A1','TimeStamp',bold)
worksheet.write('B1', 'Latitude',bold)
worksheet.write('C1', 'Longitude',bold)
worksheet.write('D1', 'Velocity',bold)
worksheet.autofilter('A1:D1') #dropdown menu created for filtering
# Create a For loop to iterate through each row in the XLS file, starting at row 2 to skip the headers
for r, row in enumerate(data, start=1): #where you want to start printing results inside workbook
for c, col in enumerate(row):
worksheet.write_column(r,0, t_stamp, date_format)
worksheet.write_column(r,1, lati)
worksheet.write_column(r,2, long)
worksheet.write_column(r,3, v)
workbook.close()
f.close()
I am using a dummy gps cache with these lines in a txt file. Notice the GPRMC have a different year in row[9] == 01,02,03
$GPRMC,002454,A,3553.5295,N,13938.6570,E,0.0,43.1,180701,7.1,W,A*3F
$GPRMB,A,,,,,,,,,,,,A,A*0B
$GPGGA,002455,3553.5295,N,13938.6570,E,1,05,2.2,18.3,M,39.0,M,,*7F
$GPRMC,002456,A,3553.5321,N,13938.6581,E,0.0,43.1,180702,7.1,W,A*3D
$GPRMC,104715.20,A,5100.2111,N,00500.0006,E,21.7,003.0,140803,01.,W*70
My results being printed out looks the way that they are expected to...
- - - - - - - - - - - - -
garmin etrex summit.txt has 5 rows of data
- - - - - - - - - - - - -
{'$GPRMC': 3, '$GPGGA': 1, '$GPRMB': 1}
- - - - - - - - - - - - -
Print data inside garmin etrex summit.txt type y:
ok
x,y: 139.64428333333333 35.892158333333334
2000-07-18 00:24:54
x,y: 139.64430166666668 35.892201666666665
2001-07-18 00:24:56
x,y: 5.00001 51.00351833333333
2003-08-14 10:47:15
- - - - - - - - - - - - -
lati: [ 35.89215833 35.89220167 51.00351833]
- - - - - - - - - - - - -
long: [ 139.64428333 139.64430167 5.00001 ]
- - - - - - - - - - - - -
v: [ 0. 0. 40.1884]
- - - - - - - - - - - - -
date: [datetime.datetime(2000, 7, 18, 0, 24, 54)
datetime.datetime(2001, 7, 18, 0, 24, 56)
datetime.datetime(2003, 8, 14, 10, 47, 15)]
- - - - - - - - - - - - -
But when i look at my produced xlsx file, I have the first five rows looking like this:
TimeStamp Latitude Longitude Velocity
7/18/2001 00:24:54 35.89215833 139.6442833 0
7/18/2001 00:24:54 35.89215833 139.6442833 0
7/18/2001 00:24:54 35.89215833 139.6442833 0
7/18/2001 00:24:54 35.89215833 139.6442833 0
7/18/2001 00:24:54 35.89215833 139.6442833 0
7/18/2002 00:24:56 35.89220167 139.6443017 0
8/14/2003 10:47:15 51.00351833 5.00001 40.1884
So my issue is that I get 5 of the same first 'query' and then the other 2 iteration of '$GPRMC'
Where am i going wrong?

Related

How to fix 'ValueError: shapes (1,3) and (1,1) not aligned: 3 (dim 1) != 1 (dim 0)' error in numpy

I am currently learning about how to code neural networks in numpy/python. I used the code from this tutorial and tried to adapt it to make an importable module. However, when i tried using my own dataset. It threw a numpy error ValueError: shapes (1,3) and (1,1) not aligned: 3 (dim 1) != 1 (dim 0).
I have already tried reshaping all of the matrices from (x,) to (x,1) but with no success. After a bit of reading around, transposing the arrays was also meant to fix the issue, but i tried that as well and no success there either.
Here is the module (called hidden_net):
import numpy as np
class network:
def __init__(self,layer_num,learning_rate=0.7,seed=None,logistic_coefficent=0.9):
self.logistic_coefficent=logistic_coefficent
self.learning_rate=learning_rate
self.w0 = np.random.random((layer_num[0],layer_num[1]))
self.w1 = np.random.random((layer_num[1],layer_num[2]))
np.random.seed(seed)
def sigmoid(self,x,reverse=False):
if(reverse==True):
return x*(1-x)
return 1/(1+np.exp(-x*self.logistic_coefficent))
def train(self,inps,outs):
inps=np.array(inps)
layer0 = inps
layer1 = self.sigmoid(np.dot(layer0,self.w0))
layer2 = self.sigmoid(np.dot(layer1,self.w1))
layer2_error = outs - layer2
layer2_delta = layer2_error*self.sigmoid(layer2,reverse=True)#*self.learning_rate
layer1_error = layer2_delta.dot(self.w1.T)
layer1_delta = layer1_error * self.sigmoid(layer1,reverse=True)#*self.learning_rate
layer1= np.reshape(layer1, (layer1.shape[0], 1))
layer2= np.reshape(layer2, (layer2.shape[0], 1))
layer1_delta= np.reshape(layer1_delta, (layer1_delta.shape[0], 1)) #Other attempts to reshape to avoid this error
layer2_delta= np.reshape(layer2_delta, (layer2_delta.shape[0], 1))
self.w1 += layer1.T.dot(layer2_delta)
self.w0 += layer0.T.dot(layer1_delta)
Here is the program importing that module:
import hidden_net
op=open('Mall_Customers_Mod.txt','r')
full=op.read()
op.close()
full_lines=full.split('\n')
training_lines=[]
for i in range(174):
training_lines.append(full_lines[0])
del full_lines[0]
training_inputs=[]
training_outputs=[]
for j in training_lines:
training_inputs.append([float(j.split(',')[0]),float(j.split(',')[1])])
training_outputs.append(float(j.split(',')[2]))
testing_lines=full_lines
testing_inputs=[]
testing_outputs=[]
for l in testing_lines:
testing_inputs.append([float(l.split(',')[0]),float(l.split(',')[1])])
testing_outputs.append(float(l.split(',')[2]))
nn=hidden_net.network([2,3,1],seed=10)
for i in range(1000):
for cur in range(len(training_inputs)):
nn.train(training_inputs[cur],training_outputs[cur])
and here is part of my data set (Mall_Customers_Mod.txt)
-1,19,15
-1,21,15
1,20,16
1,23,16
1,31,17
1,22,17
1,35,18
1,23,18
-1,64,19
1,30,19
-1,67,19
1,35,19
1,58,20
1,24,20
-1,37,20
-1,22,20
1,35,21
-1,20,21
-1,52,23
The error is on line 30:
self.w1 += layer1.T.dot(layer2_delta)
ValueError: shapes (1,3) and (1,1) not aligned: 3 (dim 1) != 1 (dim 0)
Also sorry, i know i am meant to avoid pasting entire files, but it seems pretty unavoidable here
The lines below are wrong, layer0 is the input layer and does not contain any neurons.
self.w1 += layer1.T.dot(layer2_delta)
self.w0 += layer0.T.dot(layer1_delta)
They should be:
self.w1 += layer2.T.dot(layer2_delta)
self.w0 += layer1.T.dot(layer1_delta)
All the reshape operations should be removed too. The updated train function
def train(self,inps,outs):
inps=np.array(inps)
layer0 = inps
layer1 = self.sigmoid(np.dot(layer0,self.w0))
layer2 = self.sigmoid(np.dot(layer1,self.w1))
layer2_error = outs - layer2
layer2_delta = layer2_error*self.sigmoid(layer2,reverse=True)#*self.learning_rate
layer1_error = layer2_delta.dot(self.w1.T)
layer1_delta = layer1_error * self.sigmoid(layer1,reverse=True)#*self.learning_rate
self.w1 += layer2.T.dot(layer2_delta)
self.w0 += layer1.T.dot(layer1_delta)

Manipulating character arrays quickly in R data.table [duplicate]

This question already has answers here:
Faster way to read fixed-width files
(4 answers)
Closed 4 years ago.
I have a huge datatset (14GB, 200 Mn rows) of character vector. I've fread it (took > 30 mins on 48 core 128 GB server). The string contains concatenated information on various fields. For instance, the first row of my table looks like:
2014120900000001091500bbbbcompany_name00032401
where the first 8 characters represent date in YYYYMMDD format, next 8 characters are id, next 6 the time in HHMMSS format and then next 16 are name (prefixed with b's) and the last 8 are price (2 decimal places).
I need to transfer the above 1 column data.table into 5 columns: date, id, time, name, price.
For the above character vector that will turn out to be: date = "2014-12-09", id = 1, time = "09:15:00", name = "company_name", price = 324.01
I am looking for a (very) fast and efficient dplyr / data.table solution. Right now I am doing it with using substr:
date = as.Date(substr(d, 1, 8), "%Y%m%d");
and it's taking forever to execute!
Update: With readr::read_fwf I am able to read the file in 5-10 mins. Apparently, the reading is faster than fread. Below is the code:
f = "file_name";
num_cols = 5;
col_widths = c(8,8,6,16,8);
col_classes = "ciccn";
col_names = c("date", "id", "time", "name", "price");
# takes 5-10 mins
data = readr::read_fwf(file = f, col_positions = readr::fwf_widths(col_widths, col_names), col_types = col_classes, progress = T);
setDT(data);
# object.size(data) / 2^30; # 17.5 GB
A possible solution:
library(data.table)
library(stringi)
widths <- c(8,8,6,16,8)
sp <- c(1, cumsum(widths[-length(widths)]) + 1)
ep <- cumsum(widths)
DT[, lapply(seq_along(sp), function(i) stri_sub(V1, sp[i], ep[i]))]
which gives:
V1 V2 V3 V4 V5
1: 20141209 00000001 091500 bbbbcompany_name 00032401
Including some additional processing to get the desired result:
DT[, lapply(seq_along(sp), function(i) stri_sub(V1, sp[i], ep[i]))
][, .(date = as.Date(V1, "%Y%m%d"),
id = as.integer(V2),
time = as.ITime(V3, "%H%M%S"),
name = sub("^(bbbb)","",V4),
price = as.numeric(V5)/100)]
which gives:
date id time name price
1: 2014-12-09 1 09:15:00 company_name 324.01
But you are actually reading a fixed width file. So could also consider read.fwf from base R or read_fwffrom readr or write your own fread.fwf-function like I did a while ago:
fread.fwf <- function(file, widths, enc = "UTF-8") {
sp <- c(1, cumsum(widths[-length(widths)]) + 1)
ep <- cumsum(widths)
fread(file = file, header = FALSE, sep = "\n", encoding = enc)[, lapply(seq_along(sp), function(i) stri_sub(V1, sp[i], ep[i]))]
}
Used data:
DT <- data.table(V1 = "2014120900000001091500bbbbcompany_name00032401")
Maybe your solution is not so bad.
I am using this data:
df <- data.table(text = rep("2014120900000001091500bbbbcompany_name00032401", 100000))
Your solution:
> system.time(df[, .(date = as.Date(substr(text, 1, 8), "%Y%m%d"),
+ id = as.integer(substr(text, 9, 16)),
+ time = substr(text, 17, 22),
+ name = substr(text, 23, 38),
+ price = as.numeric(substr(text, 39, 46))/100)])
user system elapsed
0.17 0.00 0.17
#Jaap solution:
> library(data.table)
> library(stringi)
>
> widths <- c(8,8,6,16,8)
> sp <- c(1, cumsum(widths[-length(widths)]) + 1)
> ep <- cumsum(widths)
>
> system.time(df[, lapply(seq_along(sp), function(i) stri_sub(text, sp[i], ep[i]))
+ ][, .(date = as.Date(V1, "%Y%m%d"),
+ id = as.integer(V2),
+ time = V3,
+ name = sub("^(bbbb)","",V4),
+ price = as.numeric(V5)/100)])
user system elapsed
0.20 0.00 0.21
An attempt with read.fwf:
> setClass("myDate")
> setAs("character","myDate", function(from) as.Date(from, format = "%Y%m%d"))
> setClass("myNumeric")
> setAs("character","myNumeric", function(from) as.numeric(from)/100)
>
> ff <- function(x) {
+ file <- textConnection(x)
+ read.fwf(file, c(8, 8, 6, 16, 8),
+ col.names = c("date", "id", "time", "name", "price"),
+ colClasses = c("myDate", "integer", "character", "character", "myNumeric"))
+ }
>
> system.time(df[, as.list(ff(text))])
user system elapsed
2.33 6.15 8.49
All outputs are the same.
Maybe try using matrix with numeric instead of data.frame. Aggregation should take less time.

Apache Solr heatmap : How to convert in usable coordinate int2d array returned by heatmap

I'm using faceting heatmap on a spatial field which then returns a 2d array like this
"counts_ints2D",
[
null,
null,
null,
null,
[
0,
8,
4,
0,
0,
0,
0,
0,
0,
...
I want to locate those cluster on the map but the problem is that I don't know how to convert that 2d array in geo coordinates.
There's absolutely no documentation out there showing what to do with those integer.
Can somebody give some guidance ?
Going with the data you gave for Glasgow, and using the formula given in the comments, lets explore the coordinates in a python repl:
# setup
>>> minX = -180
>>> maxX = 180
>>> minY = -53.4375
>>> maxY = 74.53125
>>> columns = 256
>>> rows = 91
# calculate widths
>>> bucket_width = (maxX - minX) / columns
>>> bucket_width
1.40625
>>> bucket_height = (maxY - minY) / rows
>>> bucket_height
1.40625
# calculate area for bucket in heatmap facet for x = 124, y = 13
# point in lower left coordinate
>>> lower_left = {
... 'lat': maxY - (13 + 1) * bucket_height,
... 'lon': minX + 124 * bucket_width,
... }
>>> lower_left
{'lat': 54.84375, 'lon': -5.625}
# point in upper right
>>> upper_right = {
... 'lat': maxY - (13 + 1) * bucket_height + bucket_height,
... 'lon': minX + 124 * bucket_width + bucket_width,
... }
>>> upper_right
{'lat': 56.25, 'lon': -4.21875}
Let's graph these points on a map, courtesy of open street map. We generate a small CSV snippet we can import on umap (select the up arrow, choose 'csv' as the type and enter content into the text box). To our coordinates to show:
>>> bbox = [
... "lat,lon,description",
... str(lower_left['lat']) + "," + str(lower_left['lon']) + ",ll",
... str(upper_right['lat']) + "," + str(lower_left['lon']) + ",ul",
... str(upper_right['lat']) + "," + str(upper_right['lon']) + ",uu",
... str(lower_left['lat']) + "," + str(upper_right['lon']) + ",lu",
... ]
>>> print("\n".join(bbox))
lat,lon,description
54.84375,-5.625,ll
56.25,-5.625,ul
56.25,-4.21875,uu
54.84375,-4.21875,lu
After pasting these points into the import box creating the layer, we get this map:
Map based on Open Street Map data through uMap. This area encloses Glasgow as you expected.
Here's some code that takes 180th meridian (date line) wrapping into account:
$columns = $heatmap['columns'];
$rows = $heatmap['rows'];
$minX = $heatmap['minX'];
$maxX = $heatmap['maxX'];
$minY = $heatmap['minY'];
$maxY = $heatmap['maxY'];
$counts = $heatmap['counts_ints2D'];
// If our min longitude is greater than max longitude, we're crossing
// the 180th meridian (date line).
$crosses_meridian = $minX > $maxX;
// Bucket width needs to be calculated differently when crossing the
// meridian since it wraps.
$bucket_width = $crosses_meridian
? $bucket_width = (360 - abs($maxX - $minX)) / $columns
: $bucket_width = ($maxX - $minX) / $columns;
$bucket_height = ($maxY - $minY) / $rows;
$points = [];
foreach ($counts as $rowIndex => $row) {
if (!$row) continue;
foreach ($row as $columnIndex => $column) {
if (!$column) continue;
$point = []
$point['count'] = $column;
// Put the count in the middle of the bucket (adding a half height and width).
$point['lat'] = $maxY - (($rowIndex + 1) * $bucket_height) + ($bucket_height / 2);
$point['lng'] = $minX + ($columnIndex * $bucket_width) + ($bucket_width / 2);
// We crossed the meridian, so wrap back around to negative.
if ($point['lng'] > 180) {
$point['lng'] = -1 * (180 - ($point['lng'] % 180));
}
$points[] = $point;
}
}

Why I am not getting right value when pushing it to an array?

I have some data in the following format.
# AB Tests
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
abTests:
productRanking:
version: 4
groups: [
ratio:
default: 1
us: 0.90
me: 0.0
value: "LessPopularityEPC"
,
ratio:
default: 0
us: 0.1
value: "CtrEpcJob"
,
ratio:
default: 0
me: 1.0
value: "RandomPerVisitor"
]
# Routes
I want the following output as a string array:
productRanking:LessPopularityEPC
productRanking:CtrEpcJob
productRanking:RandomPerVisitor
I am using the following code which will separate the key and values from the data & store them into an array
START_REGEXP = /# AB Tests/
END_REGEXP = /# Routes/
COMMENT_EXP = /#/
#Function to fetch the key:value & store them into array
def Automate_AB_tests.store_key_value(input_file)
prev_line = ""
curr_line = ""
array = []
flag = false
IO.foreach(input_file) do |line|
prev_line = curr_line
curr_line = line
flag = true if line =~ START_REGEXP
if flag
unless line =~ COMMENT_EXP
if line.include? 'version: '
key = prev_line
puts key #productRanking: sabt:
end
if line.include? 'value: '
value = line.delete('\n').delete('"').split[1] #LessPopularityEPC CtrlEpcJob RandomPerVisitor
array << "#{key}:#{value}"
end
end
flag = false if line =~ END_REGEXP
end
end
puts array
end
It is fetching the keys but not storing those keys into stringArray. If anyone can point out what's wrong with my code then it would be really great. I am getting output as below:
productRanking:
:LessPopularityEPC
:CtrEpcJob
:RadomPerVisitor
Since for some reason you apparently can't or won't install Node.js, which would make really, really short work of this, you're stuck doing an ugly hack.
I propose an alternate ugly hack: CSON isn't all that different from YAML. Do some simple substitutions to turn it into YAML and then parse that in Ruby.
Caveat emptor: Like all ugly hacks, this is super fragile. It will probably break as soon as you try to take a vacation. Use at your own risk.
require "yaml"
data = <<END
# AB Tests
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
abTests:
productRanking:
version: 4
groups: [
ratio:
default: 1
us: 0.90
me: 0.0
value: "LessPopularityEPC"
,
ratio:
default: 0
us: 0.1
value: "CtrEpcJob"
,
ratio:
default: 0
me: 1.0
value: "RandomPerVisitor"
]
# Routes
END
AB_TESTS_SECTION_EXPR = /^( +)abTests:\n.+(?=^\1[^ ])/m
# Extract text between "# AB Tests" and "# Routes"
ab_tests = data[AB_TESTS_SECTION_EXPR]
# Turn the CSON array into a YAML array by removing the square brackets and
# commas and inserting a `-` before each "ratio:"
yaml = ab_tests.gsub(/\s+\[$/, '')
.gsub(/ ratio:\s*$/, '- ratio:')
.gsub(/^\s*[,\]]\s*$/, '')
puts yaml
This will print the following valid YAML:
abTests:
productRanking:
version: 4
groups:
- ratio:
default: 1
us: 0.90
me: 0.0
value: "LessPopularityEPC"
- ratio:
default: 0
us: 0.1
value: "CtrEpcJob"
- ratio:
default: 0
me: 1.0
value: "RandomPerVisitor"
Now we just need to parse the YAML into Ruby and extract the data we need:
hsh = YAML.load(yaml)
hsh["abTests"].each do |key, val|
val["groups"].each do |group|
puts "#{key}:#{group['value']}"
end
end
# => productRanking:LessPopularityEPC
# productRanking:CtrEpcJob
# productRanking:RandomPerVisitor

OpenMDAO 1.5 : Running DOEdriver with array as desvar

I have used the example described here (http://openmdao.readthedocs.org/en/1.5.0/usr-guide/tutorials/doe-drivers.html?highlight=driver) to show my problem. I want to use the same approach for one component were "params" are array and no longer float . See example below
from openmdao.api import IndepVarComp, Group, Problem, ScipyOptimizer, ExecComp, DumpRecorder, Component
from openmdao.drivers.latinhypercube_driver import LatinHypercubeDriver, OptimizedLatinHypercubeDriver
import numpy as np
class Paraboloid(Component):
""" Evaluates the equation f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3 """
def __init__(self):
super(Paraboloid, self).__init__()
self.add_param('x', val=0.0)
self.add_param('y', val=0.0)
self.add_output('f_xy', val=0.0)
def solve_nonlinear(self, params, unknowns, resids):
"""f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3
"""
x = params['x']
y = params['y']
unknowns['f_xy'] = (x-3.0)**2 + x*y + (y+4.0)**2 - 3.0
def linearize(self, params, unknowns, resids):
#""" Jacobian for our paraboloid."""
x = params['x']
y = params['y']
J = {}
J['f_xy', 'x'] = 2.0*x - 6.0 + y
J['f_xy', 'y'] = 2.0*y + 8.0 + x
return J
class ParaboloidArray(Component):
""" Evaluates the equation f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3 """
def __init__(self):
super(ParaboloidArray, self).__init__()
self.add_param('X', val=np.array([0., 0.]))
self.add_output('f_xy', val=0.0)
def solve_nonlinear(self, params, unknowns, resids):
"""f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3
"""
x = params['X'][0]
y = params['y'][1]
unknowns['f_xy'] = (x-3.0)**2 + x*y + (y+4.0)**2 - 3.0
top = Problem()
root = top.root = Group()
root.add('p1', IndepVarComp('x', 50.0), promotes=['*'])
root.add('p2', IndepVarComp('y', 50.0), promotes=['*'])
root.add('comp', Paraboloid(), promotes=['*'])
top.driver = OptimizedLatinHypercubeDriver(num_samples=4, seed=0, population=20, generations=4, norm_method=2)
top.driver.add_desvar('x', lower=-50.0, upper=50.0)
top.driver.add_desvar('y', lower=-50.0, upper=50.0)
top.driver.add_objective('f_xy')
top.setup()
top.run()
top.cleanup()
###########################
print("case float ok")
top = Problem()
root = top.root = Group()
root.add('p1', IndepVarComp('X', np.array([50., 50.])), promotes=['*'])
root.add('comp', ParaboloidArray(), promotes=['*'])
top.driver = OptimizedLatinHypercubeDriver(num_samples=4, seed=0, population=20, generations=4, norm_method=2)
top.driver.add_desvar('X', lower=np.array([-50., -50.]), upper=np.array([50., 50.]))
top.driver.add_objective('f_xy')
top.setup()
top.run()
top.cleanup()
I obtain the following error :
Traceback (most recent call last):
File "C:\Program Files (x86)\Wing IDE 101 5.0\src\debug\tserver\_sandbox.py", line 102, in <module>
File "D:\tlefeb\Anaconda2\Lib\site-packages\openmdao\core\problem.py", line 1038, in run
self.driver.run(self)
File "D:\tlefeb\Anaconda2\Lib\site-packages\openmdao\drivers\predeterminedruns_driver.py", line 108, in run
for run in runlist:
File "D:\tlefeb\Anaconda2\Lib\site-packages\openmdao\drivers\latinhypercube_driver.py", line 57, in _build_runlist
design_var_buckets = self._get_buckets(bounds['lower'], bounds['upper'])
File "D:\tlefeb\Anaconda2\Lib\site-packages\openmdao\drivers\latinhypercube_driver.py", line 101, in _get_buckets
bucket_walls = np.linspace(low, high, self.num_samples + 1)
File "D:\tlefeb\Anaconda2\Lib\site-packages\numpy\core\function_base.py", line 102, in linspace
if step == 0:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Did I misunderstood something in my way of coding ?
I get a different error than you, using the the latest OpenMDAO master, but I get an error non-the-less. There isn't anything wrong with the mode, but rather there are some bugs with using array variables for DOEs. I've added a bug-fix story to the OpenMDAO backlog, which we'll hopefully be able to deal with in the next couple weeks. We'd gladly accept a pull request if you develop a fix before we get to it though.

Resources