Как я могу получить массив массивов массивов в Джулии? - PullRequest
0 голосов
/ 01 июня 2018

Я новичок в Юлии, поэтому не судите меня, пожалуйста (ха-ха)

Это моя ситуация: мне нужно было сохранить несколько матриц 2x2x2, элементы которых были векторами из 4 элементов, но теперь, когда япопытаться извлечь их из файла, я не могу !!!

Вот что я сделал:

Чтобы создать эти матрицы, я сделал эту функцию

function InitialConf(L_=2,S_=2,T_=2,Dim_=4)
  Conf_=Array{Array{Float64,1}}(L_,S_,T_)
  for i_ = 1:L_, j_=1:S_,k_=1:T_
    Conf_[i_,j_,k_]=RanUniVec(Dim_)
  end
  return Conf_ 
end

Где RanUniVec (Dim _) - это функция, которая создает эти векторы четырех измерений со специальными характеристиками, которые не важны для этого обсуждения:

function RanUniVec(Dim_)
  vector_=Array{Float64}(Dim_)
  while true
    for i_ in 1:Dim_
      vector_[i_]=UniformRand(-1,1)
    end
    if norm(vector_)<1 && norm(vector_)>0.5
      break
    end
  end
  vector_=normalize(vector_) # 2-norm
  return vector_ 
end


function UniformRand(a_,b_)
  rand_=(b_-a_)*rand()+a_
  return rand_
end

Мне понадобились две из этих матриц (например,) поэтому я сделал следующее:

States=[]
Conf1=InitialConf()
Conf2=InitialConf()
push!(States,Conf1)
push!(States,Conf2)

f=open("Info.txt","w") do f
    write(f,"$States")
end

Это сделало файл Info.txt , где хранится моя информация, но когда я пытаюсь снова получить массив States из этого файла Джулия говорит мне, что он не может

f=readlines("Info.txt")
States=parse(f)

ERROR: MethodError: no method matching parse(::Array{String,1})
Closest candidates are:
  parse(::Type{IPv4}, ::AbstractString) at socket.jl:167
  parse(::Type{IPv6}, ::AbstractString) at socket.jl:218
  parse(::Type{DateTime}, ::AbstractString, ::DateFormat{Symbol("yyyy-mm-dd\\THH:MM:SS.s"),Tuple{Base.Dates.DatePart{'y'},Base.Dates.Delim{Char,1},Base.Dates.DatePart{'m'},Base.Dates.Delim{Char,1},Base.Dates.DatePart{'d'},Base.Dates.Delim{Char,1},Base.Dates.DatePart{'H'},Base.Dates.Delim{Char,1},Base.Dates.DatePart{'M'},Base.Dates.Delim{Char,1},Base.Dates.DatePart{'S'},Base.Dates.Delim{Char,1},Base.Dates.DatePart{'s'}}}) at dates/parse.jl:202

...

Знаете ли вы, как я могу снова получить мой массив State ?

Ответы [ 2 ]

0 голосов
/ 02 июня 2018

Не прямой ответ на ваш конкретный вопрос, а общая рекомендация для дальнейшего развития.Чтобы сохранить данные на диск и перезагрузить их позже, отдайте предпочтение таким форматам, как JLD2.jl.

. Вы сохраняете с помощью

@save "filename.jld2" ARRAY

и загружаете с помощью

@load "filename.jld2" ARRAY

без необходимости выяснять, какой формат вы выбрали в прошлом.Сохраняет много головной боли со сложными структурами данных.

0 голосов
/ 01 июня 2018

В общем, вы должны использовать рекомендацию Колина из комментария в долгосрочной перспективе.Вот что вы можете сделать, если у вас уже есть эти текстовые файлы.Я буду использовать меньший пример.

Предположим, ваш исходный массив состоит из двух массивов 2x2x2.Вот пример, который я буду использовать:

julia> z
2-element Array{Array{Int64,3},1}:
 [1 2; 3 4]

[10 20; 30 40]
 [1 2; 3 4]

[10 20; 30 40]

julia> z[1]
2×2×2 Array{Int64,3}:
[:, :, 1] =
 1  2
 3  4

[:, :, 2] =
 10  20
 30  40

julia> z[2]
2×2×2 Array{Int64,3}:
[:, :, 1] =
 1  2
 3  4

[:, :, 2] =
 10  20
 30  40

Теперь он будет сохранен в файл в виде следующей строки:

julia> repr(z)
"Array{Int64,3}[[1 2; 3 4]\n\n[10 20; 30 40], [1 2; 3 4]\n\n[10 20; 30 40]]"

И разбор этой строки явно не удастся.Вам нужно отредактировать свои файлы, добавив cat вызов метода для каждой записи большого массива и передать измерение 3 в качестве того, на котором вы хотите их отследить.

Это означает, чтоИсходное содержимое файла сохранения:

Array{Int64,3}[[1 2; 3 4]

[10 20; 30 40], [1 2; 3 4]

[10 20; 30 40]]

Этот файл должен содержать:

Array{Int64,3}[cat(3, [1 2; 3 4], [10 20; 30 40]),
               cat(3, [1 2; 3 4], [10 20; 30 40])]

Эти изменения могут быть выполнены вручную или вы можете написать программу длявыполнить преобразование (необходимо заменить , на ), cat(3,; \n\n на ,; убедитесь, что добавлены первые cat и последние ), так как они не будут перехвачены первыми двумя правилами).

Теперь, если вы прочитаете его в виде строки, вы можете оценить результат его анализа:

julia> s = """Array{Int64,3}[cat(3, [1 2; 3 4], [10 20; 30 40]),
                          cat(3, [1 2; 3 4], [10 20; 30 40])]"""
"Array{Int64,3}[cat(3, [1 2; 3 4], [10 20; 30 40]),\ncat(3, [1 2; 3 4], [10 20; 30 40])]"

julia> eval(parse(s))[2]
2×2×2 Array{Int64,3}:
[:, :, 1] =
 1  2
 3  4

[:, :, 2] =
 10  20
 30  40

Обратите внимание, однако, что все это не рекомендуется - лучше использоватьпакеты, которые Колин рекомендовал сделать это.

...