Skip to content

Commit c2901d8

Browse files
committed
Update
1 parent 832fe53 commit c2901d8

File tree

2 files changed

+218
-34
lines changed

2 files changed

+218
-34
lines changed

src/FileFormats/NL/read.jl

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,17 @@ function _next(::Type{Int}, io::IO, model::_CacheModel)
120120
return y
121121
end
122122

123+
function _next(::Type{Cchar}, io::IO, model::_CacheModel)
124+
if model.is_binary
125+
return read(io, Cchar)
126+
end
127+
byte = UInt8(' ')
128+
while byte == UInt8(' ')
129+
byte = read(io, UInt8)
130+
end
131+
return Cchar(byte)
132+
end
133+
123134
"""
124135
_read_til_newline(io::IO, model::_CacheModel)
125136
@@ -513,22 +524,18 @@ end
513524
function _parse_section(io::IO, ::Val{'r'}, model::_CacheModel)
514525
_read_til_newline(io, model)
515526
for i in 1:length(model.constraint_lower)
516-
type = if model.is_binary
517-
parse(Int, read(io, Char))
518-
else
519-
_next(Int, io, model)
520-
end
521-
if type == 0
527+
type = _next(Cchar, io, model)
528+
if type == Cchar('0')
522529
model.constraint_lower[i] = _next(Float64, io, model)
523530
model.constraint_upper[i] = _next(Float64, io, model)
524-
elseif type == 1
531+
elseif type == Cchar('1')
525532
model.constraint_upper[i] = _next(Float64, io, model)
526-
elseif type == 2
533+
elseif type == Cchar('2')
527534
model.constraint_lower[i] = _next(Float64, io, model)
528-
elseif type == 3
535+
elseif type == Cchar('3')
529536
# Free constraint
530537
else
531-
@assert type == 4
538+
@assert type == Cchar('4')
532539
value = _next(Float64, io, model)
533540
model.constraint_lower[i] = value
534541
model.constraint_upper[i] = value
@@ -541,22 +548,18 @@ end
541548
function _parse_section(io::IO, ::Val{'b'}, model::_CacheModel)
542549
_read_til_newline(io, model)
543550
for i in 1:length(model.variable_lower)
544-
type = if model.is_binary
545-
parse(Int, read(io, Char))
546-
else
547-
_next(Int, io, model)
548-
end
549-
if type == 0
551+
type = _next(Cchar, io, model)
552+
if type == Cchar('0')
550553
model.variable_lower[i] = _next(Float64, io, model)
551554
model.variable_upper[i] = _next(Float64, io, model)
552-
elseif type == 1
555+
elseif type == Cchar('1')
553556
model.variable_upper[i] = _next(Float64, io, model)
554-
elseif type == 2
557+
elseif type == Cchar('2')
555558
model.variable_lower[i] = _next(Float64, io, model)
556-
elseif type == 3
559+
elseif type == Cchar('3')
557560
# Free variable
558561
else
559-
@assert type == 4
562+
@assert type == Cchar('4')
560563
value = _next(Float64, io, model)
561564
model.variable_lower[i] = value
562565
model.variable_upper[i] = value

test/FileFormats/NL/read.jl

Lines changed: 195 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -277,13 +277,13 @@ function test_parse_r()
277277
write(
278278
io,
279279
"""
280-
r# can stick a comment anywhere
281-
1 3.3
282-
3
283-
0 1.1 2.2 # can stick a comment anywhere
284-
4 5.5
285-
2 4.4# can stick a comment anywhere
286-
""",
280+
r# can stick a comment anywhere
281+
1 3.3
282+
3
283+
0 1.1 2.2 # can stick a comment anywhere
284+
4 5.5
285+
2 4.4# can stick a comment anywhere
286+
""",
287287
)
288288
seekstart(io)
289289
NL._parse_section(io, model)
@@ -300,13 +300,13 @@ function test_parse_b()
300300
write(
301301
io,
302302
"""
303-
b# can stick a comment anywhere
304-
1 3.3
305-
3# can stick a comment anywhere
306-
0 1.1 2.2
307-
4 5.5
308-
2 4.4 # can stick a comment anywhere
309-
""",
303+
b# can stick a comment anywhere
304+
1 3.3
305+
3# can stick a comment anywhere
306+
0 1.1 2.2
307+
4 5.5
308+
2 4.4 # can stick a comment anywhere
309+
""",
310310
)
311311
seekstart(io)
312312
NL._parse_section(io, model)
@@ -813,6 +813,187 @@ function test_nl_read_scalar_affine_function()
813813
return
814814
end
815815

816+
function test_binary_next_Float64()
817+
model = NL._CacheModel()
818+
model.is_binary = true
819+
sequence = [0.0, 1.0, -2.0, 1.234, 1e-12]
820+
io = IOBuffer()
821+
for s in sequence
822+
write(io, s)
823+
end
824+
seekstart(io)
825+
for s in sequence
826+
@test NL._next(Float64, io, model) === s
827+
end
828+
return
829+
end
830+
831+
function test_binary_next_Int()
832+
model = NL._CacheModel()
833+
model.is_binary = true
834+
sequence = Int32[0, 1, 2, -3, -5, typemax(Int32), typemin(Int32)]
835+
io = IOBuffer()
836+
for s in sequence
837+
write(io, s)
838+
end
839+
seekstart(io)
840+
for s in sequence
841+
@test NL._next(Int, io, model) === Int(s)
842+
end
843+
return
844+
end
845+
846+
function test_binary_read_til_newline()
847+
model = NL._CacheModel()
848+
model.is_binary = true
849+
io = IOBuffer()
850+
@test NL._read_til_newline(io, model) === nothing
851+
@test position(io) == 0
852+
return
853+
end
854+
855+
function test_parse_header_binary()
856+
model = NL._CacheModel()
857+
io = IOBuffer()
858+
write(
859+
io,
860+
"""b3 0 1 0 # problem test_simple
861+
2 1 1 0 0 # vars, constraints, objectives, ranges, eqns
862+
1 1 # nonlinear constraints, objectives
863+
0 0 # network constraints: nonlinear, linear
864+
1 2 0 # nonlinear vars in constraints, objectives, both
865+
0 0 1 1 # linear network variables; functions; arith, flags
866+
0 0 0 0 0 # discrete variables: binary, integer, nonlinear (b,c,o)
867+
1 1 # nonzeros in Jacobian, gradients
868+
0 0 # max name lengths: constraints, variables
869+
0 0 0 0 0 # common exprs: b,c,o,c1,o1
870+
""",
871+
)
872+
seekstart(io)
873+
NL._parse_header(io, model)
874+
@test model.is_binary
875+
return
876+
end
877+
878+
function test_binary_parse_O()
879+
model = NL._CacheModel()
880+
model.is_binary = true
881+
NL._resize_variables(model, 4)
882+
io = IOBuffer()
883+
write(io, Char('O'), Int32(0), Int32(0))
884+
write(io, Char('o'), Int32(2))
885+
write(io, Char('v'), Int32(0))
886+
write(io, Char('o'), Int32(2))
887+
write(io, Char('v'), Int32(2))
888+
write(io, Char('o'), Int32(2))
889+
write(io, Char('v'), Int32(3))
890+
write(io, Char('v'), Int32(1))
891+
seekstart(io)
892+
NL._parse_section(io, model)
893+
@test eof(io)
894+
@test model.sense == MOI.MIN_SENSE
895+
x = MOI.VariableIndex.(1:4)
896+
@test model.objective == :($(x[1]) * ($(x[3]) * ($(x[4]) * $(x[2]))))
897+
return
898+
end
899+
900+
function test_binary_parse_O_max()
901+
model = NL._CacheModel()
902+
model.is_binary = true
903+
NL._resize_variables(model, 4)
904+
io = IOBuffer()
905+
write(io, Char('O'), Int32(0), Int32(1), Char('v'), Int32(0))
906+
seekstart(io)
907+
NL._parse_section(io, model)
908+
@test eof(io)
909+
@test model.sense == MOI.MAX_SENSE
910+
x = MOI.VariableIndex(1)
911+
@test model.objective == :(+$x)
912+
return
913+
end
914+
915+
function test_binary_parse_x()
916+
model = NL._CacheModel()
917+
model.is_binary = true
918+
NL._resize_variables(model, 5)
919+
io = IOBuffer()
920+
write(io, Char('x'), Int32(3))
921+
write(io, Int32(0), 1.1)
922+
write(io, Int32(3), 2.2)
923+
write(io, Int32(2), 3.3)
924+
seekstart(io)
925+
NL._parse_section(io, model)
926+
@test eof(io)
927+
@test model.variable_primal == [1.1, 0.0, 3.3, 2.2, 0.0]
928+
return
929+
end
930+
931+
function test_parse_d()
932+
model = NL._CacheModel()
933+
model.is_binary = true
934+
io = IOBuffer()
935+
write(io, Char('d'), Int32(3))
936+
write(io, Int32(0), 1.1)
937+
write(io, Int32(3), 2.2)
938+
write(io, Int32(2), 3.3)
939+
seekstart(io)
940+
NL._parse_section(io, model)
941+
@test eof(io)
942+
return
943+
end
944+
945+
function test_binary_parse_r()
946+
model = NL._CacheModel()
947+
model.is_binary = true
948+
NL._resize_constraints(model, 5)
949+
io = IOBuffer()
950+
write(io, Char('r'))
951+
write(io, Cchar('1'), 3.3)
952+
write(io, Cchar('3'))
953+
write(io, Cchar('0'), 1.1, 2.2)
954+
write(io, Cchar('4'), 5.5)
955+
write(io, Cchar('2'), 4.4)
956+
seekstart(io)
957+
NL._parse_section(io, model)
958+
@test eof(io)
959+
@test model.constraint_lower == [-Inf, -Inf, 1.1, 5.5, 4.4]
960+
@test model.constraint_upper == [3.3, Inf, 2.2, 5.5, Inf]
961+
return
962+
end
963+
964+
function test_binary_parse_b()
965+
model = NL._CacheModel()
966+
model.is_binary = true
967+
NL._resize_variables(model, 5)
968+
io = IOBuffer()
969+
write(io, Char('b'))
970+
write(io, Cchar('1'), 3.3)
971+
write(io, Cchar('3'))
972+
write(io, Cchar('0'), 1.1, 2.2)
973+
write(io, Cchar('4'), 5.5)
974+
write(io, Cchar('2'), 4.4)
975+
seekstart(io)
976+
NL._parse_section(io, model)
977+
@test eof(io)
978+
@test model.variable_lower == [-Inf, -Inf, 1.1, 5.5, 4.4]
979+
@test model.variable_upper == [3.3, Inf, 2.2, 5.5, Inf]
980+
return
981+
end
982+
983+
function test_binary_parse_k()
984+
model = NL._CacheModel()
985+
model.is_binary = true
986+
NL._resize_variables(model, 3)
987+
io = IOBuffer()
988+
write(io, Char('k'), Int32(2))
989+
write(io, Int32(2))
990+
write(io, Int32(4))
991+
seekstart(io)
992+
NL._parse_section(io, model)
993+
@test eof(io)
994+
return
995+
end
996+
816997
end
817998

818999
TestNonlinearRead.runtests()

0 commit comments

Comments
 (0)